In C# you have two ways of casting one object to another. One is to use the as operator, which attempts to casting the object and either returns the successfully cast result or returns null.
Another way is to use the casting operator.
In the case where you are going to use the result of the cast immediately, Which should you use?
// option 1 var thing = GetCurrentItem(); var foo = thing as Foo; foo.DoSomething(); // option 2 var thing = GetCurrentItem(); var foo = (Foo)thing; foo.DoSomething();
Now, suppose the thing is not a Foo after all. Both options will crash, but they will crash differently.
In the first version, you will crash with a NullReferenceException at the foo.DoSomething(), and the crash dump will confirm that, yes, the foo variable is null. But the thing might not be in the crash dump. Maybe the crash dump captures only the parameters that participated in the expression that resulted in the exception. Or maybe thing was GC’d away. You can’t tell whether the problem is that GetCurrentItem returned null, or that GetCurrentItem returned an object that wasn’t a Foo. And if it wasn’t a Foo, what was it?
In the second version, there are two ways the code could crash. If the thing is null, then you will get a NullReferenceException at the foo.DoSomething(). But if the thing is the wrong kind of object, then the crash will occur at the point of the cast with an InvalidCastException. And if you’re lucky, the debugger will show you the thing that could not be cast. Even if it doesn’t, you can at least determine from the type of the exception which of the two cases you’re in.
Exercise: The following two lines of code are functionally equivalent. Which is easier to debug?
// option 1 collection.FirstOrDefault().DoSomething(); // option 2 collection.First().DoSomething();
0 comments