Cast有时会抛出异常,但"后面的解引用没有

本文关键字:引用 抛出异常 Cast quot | 更新日期: 2023-09-27 18:04:11

我希望这篇文章适合这个网站,因为我已经找到了答案,所以它更像是一个测验,而不是一个问题。

下面的c#代码可以正常工作:

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

但是如果我试着把它改成:

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

在某些情况下,我得到一个"cannot cast to IWidget"异常。

一开始我很惊讶这是怎么可能的,因为如果它不能在第二个例子中强制转换,它应该在第一个例子中抛出一个空异常。但我发现它不一定是这样的:)

这怎么可能?

Cast有时会抛出异常,但"后面的解引用没有

我猜在你的代码的其余部分发生了一些事情,使小部件对象不是"可浇注的"。Cast和"As"并不是一回事。也许这篇文章能给你一些启发。

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

它们产生不同的IL,所以这不是完全相同的事情。我想这一切都取决于您如何定义IWidget和WidgetRef。我不能确切地告诉你是什么导致了这种行为。

也许Init是一个静态方法,所以它可以在例1中运行,因为'as'不会抛出异常。

既然你说'在某些情况下',它抛出一个异常的问题不是与。init(),但与铸造。

好的,这是答案…

我所做的错误假设,即WidgetRef是一个变量或字段。它实际上是一个属性,定义如下:

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

,其中NullWidget是一个以最小方式实现IWidget的类。所以即使null被分配给WidgetRef,那也不是从它出来的!

如果执行强制转换失败,as操作符将返回null。

MSDN上as操作符

as关键字的行为与强制类型转换关键字相同,只是它会在强制类型转换失败时将对象设置为null,而不是抛出异常。