使用反射创建类型时出现问题
我得到了以下基类:
public class ValidationItem
{
public ObservableCollection<object> GetFilteredValues( ObservableCollection<object> values)
{
return new ObservableCollection<object>(); // nothing here yet
}
}
我创建了一个继承此基类型的类型,并创建了一个 getter,它将返回基类 GetFilteredValues 方法结果。
新属性应该如下所示:
public ObservableCollection<object> Values
{
get { return GetFilteredValues(_values); }
set { _values = value; }
}
这就是我所做的:
Type pType = typeof(ObservableCollection<object>);
FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, pType, FieldAttributes.Private);
PropertyBuilder propertyBuilder = tb.DefineProperty( propertyName, PropertyAttributes.HasDefault, pType, null);
MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName,
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.HideBySig,
pType, Type.EmptyTypes);
getPropMthdBldr.SetReturnType(typeof(ObservableCollection<>).MakeGenericType(typeof(object)));
ILGenerator getIL = getPropMthdBldr.GetILGenerator();
MethodInfo minfo = typeof(ValidationItem).GetMethod("GetFilteredValues", new[] { typeof(ObservableCollection<object>) }); // it's not null so everything is ok here
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldfld, fieldBuilder);
getIL.EmitCall(OpCodes.Callvirt, minfo, Type.EmptyTypes);
getIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getPropMthdBldr);
但是每次我运行应用程序并使用此创建的类型时,都会收到错误“公共语言运行时检测到无效程序”。我做错了什么?
提前致谢。
I got a following base class:
public class ValidationItem
{
public ObservableCollection<object> GetFilteredValues( ObservableCollection<object> values)
{
return new ObservableCollection<object>(); // nothing here yet
}
}
I create a type which inherits this base type and I create a getter which is going to return a base class GetFilteredValues method result.
This is how a new property should look like:
public ObservableCollection<object> Values
{
get { return GetFilteredValues(_values); }
set { _values = value; }
}
This is what I do:
Type pType = typeof(ObservableCollection<object>);
FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, pType, FieldAttributes.Private);
PropertyBuilder propertyBuilder = tb.DefineProperty( propertyName, PropertyAttributes.HasDefault, pType, null);
MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName,
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.HideBySig,
pType, Type.EmptyTypes);
getPropMthdBldr.SetReturnType(typeof(ObservableCollection<>).MakeGenericType(typeof(object)));
ILGenerator getIL = getPropMthdBldr.GetILGenerator();
MethodInfo minfo = typeof(ValidationItem).GetMethod("GetFilteredValues", new[] { typeof(ObservableCollection<object>) }); // it's not null so everything is ok here
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldfld, fieldBuilder);
getIL.EmitCall(OpCodes.Callvirt, minfo, Type.EmptyTypes);
getIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getPropMthdBldr);
But each time I run an app and use this created type, I get an error "Common Language Runtime detected an invalid program". What am I doing wrong?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您调用
GetFilteredValues
时,堆栈上唯一的东西就是ObservableCollection
When you call
GetFilteredValues
, the only thing on the stack is theObservableCollection<object>
. SinceGetFilteredValues
is an instance method, you also need to pushthis
. Add a secondLdarg_0
before the existing one so that you push it on the stack before_values
:根据 Ldfld 的文档,堆栈转换是将
因此,执行后,
您在计算堆栈上将只有字段引用(没有“this”)。要修复此问题,请复制 arg_0
这应该会有所帮助。
As per documentation to Ldfld, stack transition is the following
So after executing
you will have only field reference on the evaluation stack (without 'this'). To fix, duplicate arg_0
This should help.