有没有办法在不同类型的不同组件之间强制转换?我需要执行一个函数,其程序集已加载Assembly.Load(ReadAllBytes(...)),但它在参数转换中失败。那么,有没有办法在c#中“reinterpret_cast”对象?
修改
我的铸造问题的最基本的例子是:
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.
答案 0 :(得分:5)
除非两种类型共享继承关系,否则通用接口或其中一种类型为另一种提供转换运算符...否。
如果您需要更具体的建议,您将不得不提供一些其他详细信息,但这里是C#中投射行为的一般概述。
使用C#进行转换可以是表示保留操作,也可以是表示更改。当您将实例转换为更广泛或更窄的类型继承heirarchy,或者它实现的接口时,您正在执行保留转换的表示。您仍在处理相同的位,编译器/运行时只是确保您指定的类型对您正在处理的对象的实例有效。跨越继承heirarchies或实例未实现的接口是非法的。
对于自定义类型,表示更改转换是基本上从现有实例创建新实例的转换。您可以为类型定义自己的强制转换运算符:
public class MyType
{
public static int implicit operator int( MyType t )
{
return 42; // trivial conversion example
}
}
Conversion operators可以定义为implicit
或explicit
- 它决定编译器是否会选择为您应用它们(隐式),或者会要求您在显式转换类型时你想要一个转换(显式)。
根据您描述的内容,您可能需要编写一个实用程序类来执行从一种类型到另一种类型的转换。不幸的是,C#或.NET中没有任何内置功能可以为您完成此任务。
答案 1 :(得分:2)
如果您加载了两个不同版本的程序集,并且这两个类是兼容的(程序集的相同版本或对特定类没有更改),则一个选项是从一个实例序列化到内存中并反序列化为一个实例你需要的装配。如果由于新程序集中的更改而导致类之间可能存在差异,则必须考虑更一般的序列化问题。如果是这种情况,我建议调查DataContractSerializer,这可以支持更复杂的情况。
答案 2 :(得分:0)
最后,通过结合使用DynamicMethod,Emit-namespace和MethodUtil.ReplaceMethod(来自http://www.codeproject.com/KB/dotnet/CLRMethodInjection.aspx),设法在不兼容的类型之间进行转换。很难说哪些是必要的,哪些是可选的,如果你只对铸造感兴趣...我很高兴外部函数调用工作,即使它的参数来自不同的程序集......
答案 3 :(得分:0)
C#允许无限期输入,例如var和object,尽管这两者的行为完全不同。例如,假设您已经序列化了一个类或结构,并且无法将其强制转换为在Array.Copy方法中使用。一种解决方法是返回到您的类或结构实例化,然后将其转换为“对象”。这样,编译器将允许您在必要时将其投射到任何地方。
当然,你将失去对该类的类型安全性的保护,但对于一小段代码,这将是一个比编写整个流程方法更易于管理的解决方案。