У меня есть библиотека С#, которую внутренние клиенты настраивают с помощью VB.Net
Их скрипты бросают 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!
Если я добавлю точку останова внутри оператора неявного/расширения, он так и не достиг.
Если я удалю неявный оператор, он не будет компилироваться.
Если я выполняю эквивалентный оператор в С#:
var fc = new FooCollection();
Bar b = GetBar();
fc[fooIndex] = b //it works!
Странно - похоже, что компилятор VB.net может найти оператора трансляции, но он потерялся во время выполнения. Конечно, VB и С# IL будут здесь довольно похожими?
Код VB.net динамически компилируется - компиляция происходит при первом входе пользователя в приложение. он компилируется как VB.Net против .Net 3.5, и я не использую COM-взаимодействия.
Любые идеи?
Во-первых, я попытался бы отметить сборку С# как CLSCompliant(true)
, чтобы узнать, генерирует ли это предупреждения на implicit operator Foo
.
Ага, здесь это:
Проблема заключается в том, что VB.NET просто не вызывает функции
op_Implicit
/op_Explicit
, отображаемые кодом С#. Вы можете увидеть, что под крышкой используетсяICovertible
для выполнения всех своих преобразований.
IConvertible
выполняет все преобразования типов системных значений. Я думал, что в VB.Net вы можете сделать Public Shared Widening Operator CType(ByVal input As Bar) As Foo
и он будет таким же, как public static implicit operator Foo ( Bar input )