带隐式转换运算符的运行时InvalidCastException

时间:2009-10-13 15:23:44

标签: c# vb.net implicit-cast

我有一个内部客户端使用VB.Net配置的C#库

他们的脚本正在向InvalidCastException扔掉他们真正不应该的地方。

所以代码是这样的(大规模简化):

//C#3
public class Foo {

    public static implicit operator Foo ( Bar input )
    { 
        return new Foo( input.Property1, input.Property2 ); 
    }
}

然后在他们的VB.Net(再次大规模简化)中:

Dim fc = New FooCollection()
Dim b as Bar = GetBar()

fc(fooIndex) = b 'throws InvalidCastException at runtime!

如果我在隐式/加宽运算符中添加一个断点,它就永远不会到达。

如果我删除隐式运算符,它将无法编译。

如果我在C#中执行等效语句:

var fc = new FooCollection();
Bar b = GetBar();

fc[fooIndex] = b //it works!

奇怪 - 看起来VB.net编译器可以找到强制转换运算符,但它在运行时丢失了。当然VB和C#IL在这里会非常相似吗?

VB.net代码是动态编译的 - 编译在用户首次登录应用程序时发生。它是针对.Net 3.5编译为VB.Net的,我没有使用任何COM互操作。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

首先,我尝试将C#程序集标记为CLSCompliant(true),看看这是否会在implicit operator Foo上生成任何警告。

啊哈,here是:

  

问题是VB.NET根本不会调用C#代码公开的op_Implicit / op_Explicit函数。深入研究Visual Basic引擎,您可以看到它使用ICovertible进行所有转换。