views:

210

answers:

1

I have a C# library that internal clients configure with VB.Net

Their scripts are throwing an InvalidCastException where they really shouldn't.

So the code is something like this (massively simplified):

//C#3
public class Foo {

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

Then in their VB.Net (again massively simplified):

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

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

If I add a breakpoint inside the implicit/widening operator it's never reached.

If I remove the implicit operator it won't compile.

If I execute the equivalent statement in C#:

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

fc[fooIndex] = b //it works!

Strange - it looks like the VB.net compiler can find the cast operator but it's lost at runtime. Surely the VB and C# IL will be pretty similar here?

The VB.net code is dynamically compiled - the compile happens the first time a user logs into the app. it's being compiled as VB.Net against .Net 3.5, and I'm not using any COM interop.

Any ideas?

+1  A: 

First, I'd try and mark a C# assembly as CLSCompliant(true) to see if this generates any warnings on implicit operator Foo.

Aha, here it is:

The problem is that VB.NET simply doesn't call op_Implicit/op_Explicit functions exposed by the C# code. Delving into the Visual Basic engine you can see that under the covers it use ICovertible to do all of its conversions.

Anton Gogolev
`IConvertible` does all the system value type conversions. I thought that in VB.Net you could do `Public Shared Widening Operator CType(ByVal input As Bar) As Foo` and it would be the same as the `public static implicit operator Foo ( Bar input )`
Keith
@Anton, Good find man. Since VB doesn't call the op_Implicit functions it looks like VB will never be able to call these things in the same way as C#. Which is crazy, and yet another reason I won't touch VB.Net unless I need to...(Too many quirks with it and things C# supports, but it doesn't...)
Jason D