Ran into an interesting issue with COM-interop and Variants. In VB6, I had a "Value" Property that was of type 'Variant'. While I loathe variants, it really was required for this project since it could hold all sorts of data. Since it could hold anything, this "Value" property had a "Property Get", "Property Set" and "Property Let". I needed to use this interface in a .NET class so I used TLBIMP.EXE and get a runtime-callable-wrapper (RCW).
I referenced the RCW in my .NET project and tried to set the value property:
Dim nameField As IField = DirectCast(New Field(), IField)
nameField.Value = "Patrick"
Ran it and hit an error: Error #13 - Type Mismatch. Since it was a Variant I wasn't sure why it couldn't hold a string. I tried a few other things (like casting to System.Object) but nothing worked. So I checked out the RCW with ILDASM and noticed something interesting with the "Value" property:
.property object Value()
.custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute...
.get instance object xxx._IField::get_Value()
.set instance void xxx._IField::set_Value(object)
.other instance void xxx._IField::let_Value(object)
} // end of property _IField::Value
What was that "other" thing? I checked the "let_Value" method with ILDASM and it looked very similar to the "set_Value" method. So I did a Google search and, once again, Mattias Sjogren has the answer:
If your COM interface has both Property Set and Property Let, the
imported .NET property will always call the Set accessor, but the Let
is imported as a function named let_PropertyName that you can call
like any other function.
The Set accessor in VB6 is for object types. Since the data was string (or date, int, long, etc...) I needed to use the VB6 "Let" property. Since the RCW exposed that as a public function, I changed my code to:
And it works like a champ! Kudos to the Interop team for exposing all of this (and Mattias for the explanation!).