Fabulous Adventures In Coding
Eric Lippert is a principal developer on the C# compiler team. Learn more about Eric.
Today a question about the is and as operators: is the is operator implemented as a syntactic sugar for the as operator, or is the as operator implemented as a syntactic sugar for the is operator? More briefly, is is as or is as is?
Perhaps some sample code would be more clear. This code
bool b = x is Foo;
could be considered as a syntactic sugar for
bool b = (x as Foo) != null;
in which case is is a syntactic sugar for as. Similarly,
Foo f = x as Foo;
could be considered to be a syntactic sugar for
var temp = x;Foo f = (temp is Foo) ? (Foo)temp : (Foo)null;
in which case as is a syntactic sugar for is. Clearly we cannot have both of these be sugars because then we have an infinite regress!
The specification is clear on this point; as (in the non-dynamic case) is defined as a syntactic sugar for is.
However, in practice the CLR provides us instruction isinst, which ironically acts like as. Therefore we have an instruction which implements the semantics of as pretty well, from which we can build an implementation of is. In short, de jure is is is, and as is as is is, but de facto is is as and as is isinst.
I now invite you to leave the obvious jokes about President Clinton in the comments.
That should be default(Foo), not (Foo)null, right?
@Rohan Singh: Ah, never mind, somehow never realized that as doesn't work with value types.
so if I need to test if myObj is a MyClass, and if so, then cast myClass as a MyClass and set it equal to myObj, then what is the better, dont-drive-an-mvp-nuts way of doing it?
Because "is" can be used with both references types and value types but "as" can only be used with reference types, "as" must be defined in terms of "is" (at least for value types).
MyClass myClass = myObj as MyClass;
if (myClass != null)
Um, ignore the nonsensical "(at least for value types)"...
As if my opinion counts, and I don't want a style war, but ...
I've preferred to us 'is' only when I don't use the value in the method. If I'm using the value, I use 'as' much like @Harry above. It just seems redundant otherwise. I make the decision regardless, and I make the cast regardless.
In practice, we rarely use 'is', but it's still a nice syntactic sugar nonetheless.
I've read a zillion articles telling me that "is" is running a cast in the background so doing an "is" and then a cast would cause two casts when only one is required. This led me to using safe casting to set a variable, then check if it is null. I will need the variable later anyways. The problem occurs with value types, where I am forced to use "is" and then do a cast. This is the only thing that bothers me about it.
Nice post Eric :-) I love it when you blog about this kind of stuff.
> I now invite you to leave the obvious jokes about President Clinton in the comments.
Huh? Forgive me, but this went over my head a little. Perhaps I missed something as I'm not a US resident...
@Matthew Jones, it was during the Clinton/Monica Lewinsky scandal about whether he did or did not lie under oath. I believe it was in a video deposition that President Clinton said something to like "it depends on that the definition of is is."
Good grief, I can't t ype for squat this morning. ...Pres. Clinton said something like "it depends on what the definition of is is."
Was there a reason to use temp as opposed to just
Foo f = (x is Foo) ? (Foo)x : (Foo)null;
What if "x" is "X()" and it returns a Foo? You don't want it to be called twice. - Eric
Hi Eric, yet another fabolous post!
I do prefer using 'as' on reference types and thanks to fxCop, so does my team:)
If it is as if it is so, so be it :-)
What was was before was was was?
Before was was was, was was is!