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
. 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.
Commentary from 2020:
- This article was based on a serious question I had been asked, but of course I relished the opportunity to make silly sentences such as “is is as or is as is?”
- The bit at the end about President Clinton confused some readers, understandably. Read the explainer here for details. The TLDR is: President Clinton famously attempted to explain a lie with “it depends on what the meaning of ‘is’ is”.
- In the original comments a reader asked why anyone should care about this level of implementation detail. My response to that question gets straight to the philosophy of why I’ve written a blog for 17 years:
I reject the premise of the question; I’m not saying that you or anyone else should care about this detail. I do not necessarily write about things that are important for developers to understand; I write about things that are fabulous! And the person who gets to decide what is fabulous is me. If some of those fabulous things happen to be important, that’s super, but that’s not my aim. The name of the blog is not “Important Stuff You Should Know About Coding“.
I blog because I’ve learned a bunch of interesting stuff — interesting to me — and I like to share things that I find interesting.
-
- Another good question in the comments was “does the compiler statically analyze
is
andas
expressions?” Yes! If you write something likeif(x is string)
and we already know that x is some class typeFoo
then the expression will always be false and you get a warning.However, there are subtle problems here. The rules ofisinst
and the rules of C# are slightly different. In particular, it is illegal in C# to convertint[]
touint[]
via reference conversion, but legal in the CLR. You can therefore get into situations where the compiler will warn about “impossible” situations that are actually possible. - Several readers pointed out that there is a missing language feature: once we know that
x is Foo
is true, it should be legal to use the members ofFoo
fromx
. A form of this feature was added to C# 6;if(x is Foo f)
- Another good question in the comments was “does the compiler statically analyze