【问题标题】:C# Dynamic assembly Can't create new object and load to fieldC#动态程序集无法创建新对象并加载到字段
【发布时间】:2016-03-24 17:44:13
【问题描述】:

我正在尝试为给定类型创建新对象并将其加载到字段中,但它会抛出一个

无效程序异常。

使用本地人做同样的事情。也许在字段上做错了什么? 这不起作用:

MethodAttributes getSetAttr = MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
FieldBuilder propNameBldr = typeBuilder.DefineField("_" + PropName, PropType, FieldAttributes.Private);
propNamePropBldr = typeBuilder.DefineProperty(PropName, PropertyAttributes.HasDefault, PropType, null);
propNameGetPropMthdBldr = typeBuilder.DefineMethod("get_" + PropName, getSetAttr, PropType, Type.EmptyTypes);
ConstructorInfo baseCtor = basePropType.GetConstructor(new Type[] { });

ILGenerator propNameGetIL = propNameGetPropMthdBldr.GetILGenerator();

propNameGetIL.Emit(OpCodes.Newobj, baseCtor);
propNameGetIL.Emit(OpCodes.Stfld, PropNameBldr);

propNameGetIL.Emit(OpCodes.Ldfld, PropNameBldr);
propNameGetIL.Emit(OpCodes.Ret);
propNamePropBldr.SetGetMethod(propNameGetPropMthdBldr);

但这有效:

MethodAttributes getSetAttr = MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
FieldBuilder propNameBldr = typeBuilder.DefineField("_" + PropName, PropType, FieldAttributes.Private);
propNamePropBldr = typeBuilder.DefineProperty(PropName, PropertyAttributes.HasDefault, PropType, null);
propNameGetPropMthdBldr = typeBuilder.DefineMethod("get_" + PropName, getSetAttr, PropType, Type.EmptyTypes);
ConstructorInfo baseCtor = basePropType.GetConstructor(new Type[] { });

ILGenerator propNameGetIL = propNameGetPropMthdBldr.GetILGenerator();
LocalBuilder lc = propNameGetIL.DeclareLocal(PropType);
propNameGetIL.Emit(OpCodes.Newobj, baseCtor);
propNameGetIL.Emit(OpCodes.Stloc, PropNameBldr);

propNameGetIL.Emit(OpCodes.Ldloc, PropNameBldr);
propNameGetIL.Emit(OpCodes.Ret);
propNamePropBldr.SetGetMethod(propNameGetPropMthdBldr);

那么有什么区别,为什么首先不工作?谢谢。

【问题讨论】:

    标签: c# reflection.emit dynamic-assemblies


    【解决方案1】:

    非静态字段需要对象引用。

    生成 IL 的更好方法是使用表达式树。

    此外,您可以通过用 C# 编写等效代码并反编译编译器输出来自己回答所有此类问题。

    【讨论】:

    • 感谢您的回复。我调查了生成的IL,还有一个问题,所以这意味着我无法使用这种方法创建对象并将其放入创建的非静态字段中?
    • 当然可以,但是您需要将其存储到特定对象的字段中。不确定我是否理解您的问题...在不提供该字段所在的对象的情况下存储到非静态字段中是否有意义?!
    • 好吧,我正在尝试创建数据代理生成器,因此对于实现某些接口的给定类型,我正在尝试创建类似包装器类的东西,因此使用适当的 getter。但是问题变成了接口和输入对象类型中的类类型不同。我的意思是对象属性是接口中的“A”类型,它是“B”类型。这就是为什么尝试创建适当类型的对象并设置嵌套字段的原因。
    • 不确定我是否理解这个问题。您了解设置实例字段需要对象引用吗?在该 IL 中,您没有提供对象引用。
    • 我不完全理解这个场景。但这也不是问的问题。问一个新的。这一项完成了:您现在知道问题所在了。尝试提供对象引用。我没有看到任何这样的尝试,所以我不能帮你指出错误。
    猜你喜欢
    • 2015-04-29
    • 2020-03-07
    • 2014-05-14
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多