tags:

views:

282

answers:

3

Is there a way to force-cast between different types of different assemblies? I need to execute a function, whose assembly has been loaded with Assembly.Load(ReadAllBytes(...)), but it fails in argument casting. So, is there any way to "reinterpret_cast" objects in c#?

EDIT

Most basic example of my casting problem is:

Assembly ass = Assembly.Load(File.ReadAllBytes("external.dll"))
object other_type_instance = ass.GetType("OtherType").InvokeMember(null, BindingFlags.CreateInstance, null, null, new Object[]{});
OtherType casted_isntance = (OtherType)other_type_instance; // fails with runtime error, because there are two OtherType:s classes loaded.
+3  A: 

Unless the two types share an inheritance relationship, a common interface, or one of the types provides a conversion operator to the other ... no.

You're going to have to provide some additional details, if you want more specific advice, but here's a general rundown of casting behavior in C#.

Casting in C# can be either a representation preserving operation or a representation changing one. When you cast an instance to a wider or narrow type in it's inheritance heirarchy, or to an interface it implements, you are performing a representation preserving conversion. You're still dealing with the same bits, the compiler/runtime just ensure that the type you specify is valid for the instance of the object you are dealing with. Casts across inheritance heirarchies or to interfaces not implemented by the instance are illegal.

For custom types, representation changing casts are those that essentially create a new instance from an existing one. You can define your own cast operators for a type:

public class MyType
{
    public static int implicit operator int( MyType t )
    {
        return 42; // trivial conversion example
    }
}

Conversion operators may be defined as either implicit or explicit - which determines whether the compiler will choose to apply them for you (implicit) or will rquire you to explicitly cast the type when you want a converion (explicit).

Given what you describe, you probably need to write a utility class that performs a conversion from one type to another. Unforunately, there's nothing built into C# or .NET that can do this for you.

LBushkin
I don't think this is what the OP is asking. The question is a bit cryptic, but my understanding is that he has two different Type tokens for the same class loaded, as a result of re-loading an Assembly. This leads to fun exceptions like 'someValue' (which Intellisense shows is of type OtherType) 'is not of type OtherType'. 'Conversion' in this case is actually more akin to Marshaling.
Dan Bryant
+2  A: 

If you have two different versions of the assembly loaded and the two classes are compatible (same version of the assembly or no change to the specific class), one option is to serialize into memory from one instance and deserialize to an instance in the assembly you need. If there may be differences between the classes as a result of changes in the new assembly, you have more general serialization issues that must be considered. If that's the case, I recommend looking into DataContractSerializer, which can support more complex scenarios.

Dan Bryant
http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx may help.
sixlettervariables
A: 

Finally managed to cast between incompatible types by using a combination of DynamicMethod, Emit-namespace, and MethodUtil.ReplaceMethod (from http://www.codeproject.com/KB/dotnet/CLRMethodInjection.aspx). Hard to say which of these are necessary and which are optional if you are interested only in casting... I'm just glad that external function invokation works, even though it's arguments are from different assemblies...

AareP
Interesting, but also extremely frightening.
Dan Bryant