7

I have the following scenario:

if(xml.Descendants(ns + "Children").FirstOrDefault() != null)
{
    XElement children = xml.Descendants(ns + "Children").FirstOrDefault();
}

Is there a way I can check for null and assign the value at the same time instead of having to search for the value twice, something similar to:

//Not sure if this is correct.
if (XElement children = xml.Descendants(ns + "Children").FirstOrDefault() != null)
{

}
Xaisoft
  • 44,403
  • 86
  • 275
  • 425

6 Answers6

14

A variable assignment also returns the value. So the syntax in the form of the following will do:

SomeType someVariable;
if ((someVariable = valueToAssign) != null)
{
    // valueToAssign was not null
}

In your case:

XElement children;

if ((children = xml.Descendants(ns + "Children").FirstOrDefault()) != null)
{

}
Community
  • 1
  • 1
CodeCaster
  • 139,522
  • 20
  • 204
  • 252
4

I would do it this way:

XElement children = xml.Descendants(ns + "Children").FirstOrDefault();
if(children != null)
{
    //use children
}
Tim S.
  • 53,874
  • 7
  • 89
  • 119
2

You could just do

XElement children = xml.Descendants(ns + "Children").FirstOrDefault();

and then check for null

if (children != null) {...}
Claudio Redi
  • 65,896
  • 14
  • 126
  • 152
1

You can assign and then test the assigned value in a single statement (but not declare it):

XElement children = null;

if ((children = xml.Descendants(ns + "Children").FirstOrDefault()) != null)
{    
}

But this is functionally the same as assigning and testing afterwards:

var children = xml.Descendants(ns + "Children").FirstOrDefault();

if (children != null)
{      
}

I would favour the latter because I think it is more readable (also lets you use var).

Assignment of a null value to a variable will never itself generate an error (assuming this is just a standard local variable), subsequent use of that variable might do. So either solution above will be safe assuming xml itself isn't null.

Adam Houldsworth
  • 61,803
  • 9
  • 143
  • 182
  • Yes it returns null if no children are found, but that is what I want to avoid having to check for null and then assign the value. – Xaisoft Jun 15 '12 at 13:59
  • @Xaisoft It is functionally the same as assigning it and then checking the variable afterwards - just it does it in one line. It isn't doing any less work. – Adam Houldsworth Jun 15 '12 at 14:00
  • Nice. I'm going blind, I din't notice the double brace at first, but this works great. – Xaisoft Jun 15 '12 at 14:11
  • @Xaisoft Yeah the braces define the precedence, the "result" of the braced code is an `XElement` that can be tested for null. – Adam Houldsworth Jun 15 '12 at 14:12
  • Functionally, it's mostly the same, but you can get slightly nicer behaviour if you need to pull different content in multiple if statements: `if ((children = GetChildren1()) != null) {} elseif ((children = GetChildren2()) != null) {} elseif ((children = GetChildren3()) != null){}` though depending on what you're doing there may be a better design than that. But that's just way only calling GetChildren1/2/3 as needed rather than pre-calling all 3 then doing checks. – Chris Sinclair Jun 15 '12 at 14:14
  • 1
    @ChrisSinclair I'd say functionally the same based on "assignment before condition", but your flow is a nice take on it, and perhaps the only real reason why you might do this. I also do it in while loops: `while ((line = Console.ReadLine()).Length != 0)`, because you get a "free" assignment before the check expressed in the while condition itself, as is the end result in your example. – Adam Houldsworth Jun 15 '12 at 14:17
0

You can do this though:

null != children = xml.Descendants(ns + "Children").FirstOrDefault()
Eren Ersönmez
  • 37,498
  • 7
  • 66
  • 91
  • Just curious, why the null != first? – Xaisoft Jun 15 '12 at 14:02
  • @Xaisoft well no huge reasons -- just my taste --but if you do it the other way around you have to wrap `children = xml.Descendants(ns + "Children").FirstOrDefault()` in an extra set of parenthesis. Otherwise, the compiler will think you're trying to assign a boolean to `children` (`xml.Descendants(ns + "Children").FirstOrDefault() != null`). If you put `null != ` at the beginning you get to avoid that extra set of paranthesis -- just looks cleaner to my eyes anyway :) – Eren Ersönmez Jun 15 '12 at 15:09
0

You can use a Pattern Matching in C# 7

if(xml.Descendants(ns + "Children").FirstOrDefault() is XElement children)
{
    xml.Descendants(ns + "Children").FirstOrDefault();
}

It's a late response, but this question is showing up on top in google, and it's missing a C# 7 answer

hardkoded
  • 15,907
  • 3
  • 45
  • 56