3

Is there any situation where these two if statements will produce different results?

if(x as X != null)
{
  // Do something
}

if(x is X)
{
  // Do something
}

Edit: To clarify: I know what is the difference between the operators (in general) and what they mean. The question is if there is any situation where these two would produce different results.

aKzenT
  • 7,775
  • 2
  • 36
  • 65
  • 2
    `x as X` doesn't work if `X` is a non-nullable struct. – Michael Liu Dec 19 '13 at 16:39
  • 1
    question aside, use x is X, first one is just stupid and create extra casting – kirie Dec 19 '13 at 16:44
  • 3
    @TimSchmelter `is` returns false if the left side is `null`. They're the same in that regard. – CodesInChaos Dec 19 '13 at 16:45
  • Take a look at [this answer on another question](http://stackoverflow.com/a/496167/1324810). It's pretty extensive. – Joe Dec 19 '13 at 16:47
  • @kirie: I beg to differ - the first one is just what is done in the `var typedX = x as X; if (typedX != null) { ...` pattern, and that is at least considered to be more performant by FxCop than a check with `is` and a subsequent extra cast. – O. R. Mapper Dec 19 '13 at 16:47
  • possible duplicate of [Casting vs using the 'as' keyword in the CLR](http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr) – Joe Dec 19 '13 at 16:47
  • 1
    @CodesInChaos: i've already recognized it. [Here's](http://stackoverflow.com/questions/7640043/why-does-the-is-operator-return-false-when-given-null) the related question. Thanks for pointing that out. Sorry for deleting my comment, i noticed later your comment. – Tim Schmelter Dec 19 '13 at 16:48
  • 1
    @O.R. Mapper Isn't it better to use if(x != null && x is X), this one more readable to me – kirie Dec 19 '13 at 16:51
  • both map to the same underlying IL instruction `isinst` – CodesInChaos Dec 19 '13 at 16:51
  • @kirie: If you use `is` first and then, in the `if` block, perform a typecast, FxCop will complain about a duplicate cast that should be improved into a single `as` with a subsequent `null` comparison for performance reasons. It wouldn't create any noticeable difference in most scenarios, though. In any case, the `null` check in your statement is obsolete nonetheless, as it is basically included in the `is` check. cf. [CA1800](http://msdn.microsoft.com/en-us/library/ms182271.aspx). – O. R. Mapper Dec 19 '13 at 16:53

4 Answers4

6

There functionally is no difference between the 2 statements. In general the as version is used to avoid a double type test because you can do the following

var local = x as X;
if (local != null) { 
  // Sweet I have local! 
}

vs.

if (x is X) { 
  // This runs the type check yet again 
  var local = (X)x; 
}

If you aren't actually using the value after the type test then just use the is version

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
2

If x is a non-nullable type (or a generic type not constrained to be a nullable type) then the first option won't compile; the second is the only option.

Beyond that, they're the same.

Servy
  • 202,030
  • 26
  • 332
  • 449
2

Is there any situation where these two if statements will produce different results?

First, note that there are more restrictions on the use of as than of is, so x is X may compile in cases where (x as X) != null may not. For example, as requires that the specified type be a reference type or a nullable type; is works with non-nullable value types as well.

Assume now that both x is X and (x as X) != null are valid expressions. According to §7.10.11 of the C# 4.0 specification, "the operation E as T produces the same result as E is T ? (T)(E) : (T)null". If we plug that latter expression into (x as X) != null, we get

    (x as X) != null
==  ((x is X) ? (X)x : null) != null  // by the definition of "as"
==  (x is X) ? ((X)x != null) : (null != null)  // distribute
==  (x is X) ? true : false  // because (x is X) implies (x != null)
==  x is X

This proves that x is X and (x as X) != null are equivalent if both are valid expressions.

Michael Liu
  • 52,147
  • 13
  • 117
  • 150
0

In this case:

if(x as X != null)
{
  // Do something
}

You are first attempting to cast x to type X before comparing to null (i.e. whether the cast succeeded or not).

In this other case:

if(x is X)
{
  // Do something
}

You are simply asking whether x is of type X and no casting is done.

rdodev
  • 3,164
  • 3
  • 26
  • 34
  • Which is equivalent in the cases where it compiles – CodesInChaos Dec 19 '13 at 16:43
  • Does not answer the question whether the if statements are functionally the same... – aKzenT Dec 19 '13 at 16:50
  • 1
    @aKzenT One does the casting and the other does not, how does not answer the question? – rdodev Dec 19 '13 at 16:51
  • 1
    Question is: Is there any situation where these two if statements will produce different results? – aKzenT Dec 19 '13 at 16:52
  • @aKzenT but the question title asks something else. Even the first line of your question: *Is there a difference between the following if statements?* Please edit that to make it clear if you're that specific. – nawfal Dec 19 '13 at 16:54