我希望这适合这个网站,因为我已经找到了答案,所以这更像是一个测验,而不是一个问题。
这个C#代码没有问题:
WidgetRef = widget as IWidget;
WidgetRef.Init();
但是,如果我尝试将其更改为:
WidgetRef = (IWidget)widget;
WidgetRef.Init();
在某些情况下我得到“无法转换为IWidget”异常。
起初我觉得这是可能的,因为如果它不能在第二个例子中强制转换,它应该在第一个例子中抛出一个null异常。但我发现它不一定如此:)
这怎么可能?
答案 0 :(得分:0)
我猜你的代码中有一些东西正在使得widget对象不是“可转换的”。演员和“As”并不完全相同。也许这篇文章可能会给你一些想法。
http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx
答案 1 :(得分:0)
他们生成不同的IL,所以它完全不是一回事。我想这一切都取决于你如何定义IWidget和WidgetRef。我无法确切地告诉你是什么导致了这种行为。
也许Init是一个静态方法,所以它可以在例1中运行,因为'as'不会抛出异常。
因为你说'在某些情况下'它会抛出一个异常,问题不在于.Init(),而在于铸造。
答案 2 :(得分:0)
好的,这是答案......
我正在做的错误假设WidgetRef
是变量或字段。它实际上是一个属性,定义如下:
private IWidget _widgetRef;
private IWidget WidgetRef
{
get { return _widgetRef ?? new NullWidget(); }
set { _widgetRef = value; }
}
其中NullWidget
是以最小方式实现IWidget
的类。因此,即使null
被分配到WidgetRef
,也不是它的内容!
答案 3 :(得分:-1)
答案 4 :(得分:-1)
as关键字的行为与关键字关键字相同,只是它会将对象设置为null,而不是在转换失败时抛出异常。