Force casting one assembly type to another assembly type in c#
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 "reinter开发者_如何转开发pret_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.
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.
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.
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...
C# permits indefinite typing, such as var and object athough these two are quite different in behaviour. For example, suppose you have serialized a class or struct and cannot cast it to use in an Array.Copy method. One workaround is to go back to your class or struct instantiation and cast it as 'object' instead. That way the compiler will allow you to cast it almost anyplace when you have to.
Of course you will lose the protection of type-safety for that class, but for small pieces of code this would be a more manageable solution than writing a whole casting method.
精彩评论