开发者

Cast sometimes throws exception, but "as" followed by dereference does not

I hope this is appropriate for this site because I already figured out the answer, so it's more a quiz than a question.

This C# code works with开发者_开发百科 no problem:

WidgetRef = widget as IWidget;
WidgetRef.Init();

However if I try changing it to:

WidgetRef = (IWidget)widget;
WidgetRef.Init();

in some situations I get a "cannot cast to IWidget" exception.

At first I was dumfounded how that could be possible, because if it can't cast in the 2nd example, it should throw a null exception in the 1st example. But I discovered it ain't necessarily so :)

How is this possible?


I'd guess that there is something going on in the rest of your code that is making the widget object not "castable". Cast and "As" are not quite the same thing. Perhaps this article might give you some ideas.

http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx


They generate different IL so it's not the same thing entirely. I guess all depends on how you defined IWidget and WidgetRef. I couldn't tell you exactly what is causing the behaviour.

Maybe Init is a static method, so it can run in example 1 since 'as' doesn't throw exceptions.

Since you're saying 'in some situations' it throws an exception the problem is not with the .Init() but with the casting.


OK, here's the answer....

The incorrect assumption that I was making as that WidgetRef was a variable or field. It was actually a property, defined like this:

    private IWidget _widgetRef;
    private IWidget WidgetRef
    {
        get { return _widgetRef ?? new NullWidget(); }
        set { _widgetRef = value; }
    }

where NullWidget is a class implementing IWidget in a minimal way. So even though null was being assigned in to WidgetRef, that wasn't what was coming out of it!


The as operator will return null if it fails to perform the cast.

as operator on MSDN


The as keyword will behave the same as the casting keyword except that it will set the object to null rather than throw an exception when the cast fails.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜