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和"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,而不是抛出异常。