我有一个类,需要使用反射发射即时生成。我希望能够将此类的实例显式转换为在编译时定义的类型。
我试图重载使用反射发射定义的类型中的显式运算符,以实现此目的,但是在进行转换时会抛出错误:
System.InvalidCastException:'无法将类型为'MySourceClass'的对象转换为类型为'ExplictOperatorTest.MyTargetClass'。'
这就是我使用反射发射定义显式运算符的方式:
private static void CreateExplicitOp(TypeBuilder typeBuilder, MethodInfo conversionMethod)
{
var myType = typeBuilder.AsType();
var method = typeBuilder.DefineMethod(
"op_Explicit",
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Static,
typeof(MyTargetClass),
new Type[] { myType });
var ilGenerator = method.GetILGenerator();
var emitRecordLocal = ilGenerator.DeclareLocal(typeof(MyTargetClass));
ilGenerator.Emit(OpCodes.Nop);
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.EmitCall(OpCodes.Callvirt, conversionMethod, new Type[] { });
ilGenerator.Emit(OpCodes.Stloc_0);
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
}
这就是我想要做的没有错误的事情:
var mySourceTypeType = CreateMyType();
var mySourceTypeInstance = Activator.CreateInstance(mySourceTypeType);
// System.InvalidCastException: 'Unable to cast object of type 'MySourceClass' to type 'ExplictOperatorTest.MyTargetClass'.'
var myTarget = (MyTargetClass)mySourceTypeInstance;
我已经将我在IL中的显式声明与从等效的预定义类型生成的声明进行了比较,它看起来几乎相同,并且如果我直接调用op_Explicit
方法,它将起作用。
我的问题是:我想做什么可能?如果是这样,我哪里出问题了?
答案 0 :(得分:3)
问题在于mySourceTypeInstance
的编译时间类型为object
,因为这是Activator.CreateInstance
的返回类型。这意味着您处于这样的情况:
object obj = new XElement("foo", "text content");
string text = (string) obj; // Throws InvalidCastException
这不会使用从XElement
到string
的显式转换,因为转换的可用性是在编译时根据表达式的编译时类型选择的。 / p>
但是,如果您希望将该绑定决策移至执行时间,则可以使用dynamic
:
dynamic obj = new XElement("foo", "text content");
string text = (string) obj; // Works fine
因此,在您的情况下,对于动态生成/实例化的类型,您将使用:
var mySourceTypeType = CreateMyType();
dynamic mySourceTypeInstance = Activator.CreateInstance(mySourceTypeType);
var myTarget = (MyTargetClass)mySourceTypeInstance;