Cast有时会引发异常,但“as”后面的dereference则不会

时间:2011-08-02 17:48:51

标签: c#

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

这个C#代码没有问题:

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

但是,如果我尝试将其更改为:

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

在某些情况下我得到“无法转换为IWidget”异常。

起初我觉得这是可能的,因为如果它不能在第二个例子中强制转换,它应该在第一个例子中抛出一个null异常。但我发现它不一定如此:)

这怎么可能?

5 个答案:

答案 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)

as运算符如果无法执行强制转换,则返回null。

MSDN

上的

as运算符

答案 4 :(得分:-1)

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