.net core 使用TypeBuilder C实现带有属性的接口时如何重写setter#
我所做的是通过反射从System.Data.DataTable创建一个动态类型。但是我在实现由TypeBuilder创建的动态类型接口时遇到了麻烦 我的界面看起来像这样.net core 使用TypeBuilder C实现带有属性的接口时如何重写setter#,.net-core,reflection,interface,typebuilder,.net Core,Reflection,Interface,Typebuilder,我所做的是通过反射从System.Data.DataTable创建一个动态类型。但是我在实现由TypeBuilder创建的动态类型接口时遇到了麻烦 我的界面看起来像这样 public interface ICustomViewCols { int? CardId { get; set; } DateTime? OutDate { get; set; } string HospCode { get; set; } } 我的打字机看起来像 var aName = new
public interface ICustomViewCols
{
int? CardId { get; set; }
DateTime? OutDate { get; set; }
string HospCode { get; set; }
}
我的打字机看起来像
var aName = new AssemblyName("UniWeb.CustomView");
var ab =
AssemblyBuilder.DefineDynamicAssembly(aName,
AssemblyBuilderAccess.RunAndCollect);
var mb =
ab.DefineDynamicModule(aName.Name + ".dll");
var tb = mb.DefineType(
"CustomViewModel",
TypeAttributes.Public);
tb.AddInterfaceImplementation(typeof(ICustomViewCols));
foreach (var obj in cols)
{
var col = obj as DataColumn;
var propType = GetNullableDataType(col.DataType);
var propName = col.ColumnName;
if (propName == "HospCode" || propName == "CardId" || propName == "OutDate")
{
var getMethod = typeof(ICustomViewCols).GetProperty(propName).GetGetMethod();
var setMethod = typeof(ICustomViewCols).GetProperty(propName).GetSetMethod();
var currGetPropMthdBldr = tb.DefineMethod($"get_{propName}",
MethodAttributes.Public | MethodAttributes.Virtual,
propType, Type.EmptyTypes);
var getIl = currGetPropMthdBldr.GetILGenerator();
getIl.Emit(OpCodes.Ret);
tb.DefineMethodOverride(currGetPropMthdBldr, getMethod);
var currSetPropMthdBldr = tb.DefineMethod($"set_{propName}",
MethodAttributes.Public | MethodAttributes.Virtual,
null, new[] { propType });
var setIl = currGetPropMthdBldr.GetILGenerator();
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldc_I4_1);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Callvirt, setMethod);
setIl.Emit(OpCodes.Ret);
tb.DefineMethodOverride(currSetPropMthdBldr, setMethod);
}
else
{
var field = tb.DefineField(propName, propType, FieldAttributes.Public);
var property = tb.DefineProperty(propName, PropertyAttributes.None, propType,
new Type[] {propType});
var GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
var currGetPropMthdBldr =
tb.DefineMethod($"get_{propName}", GetSetAttr, propType, new Type[] {propType}); // Type.EmptyTypes);
var currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
var currSetPropMthdBldr =
tb.DefineMethod($"set_{propName}", GetSetAttr, null, new Type[] {propType});
var currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
property.SetGetMethod(currGetPropMthdBldr);
property.SetSetMethod(currSetPropMthdBldr);
}
}
var customViewType = tb.CreateType();
这只适用于接口中的getter,而不适用于setter。它引发系统异常。InvalidOperationException:方法“set\u HospCode”没有方法主体。有人能帮我吗?下面是我问题的后续内容
我只使用getter更改了接口
public interface ICustomViewCols
{
int Id { get; }
DateTime? OutDate { get; }
string HospCode { get; }
}
< BR>,然后我只是实现接口的吸气剂,并将设置器视为属性设置器。
private Type CreateDynamicTypeFromDataColumn(IEnumerable<DataColumn> cols)
{
//naming
var aName = new AssemblyName("UniWeb.CustomView");
var ab =
AssemblyBuilder.DefineDynamicAssembly(aName,
AssemblyBuilderAccess.RunAndCollect);
var mb =
ab.DefineDynamicModule(aName.Name + ".dll");
var tb = mb.DefineType(
"CustomViewModel",
TypeAttributes.Public);
tb.AddInterfaceImplementation(typeof(ICustomViewCols));
foreach (var col in cols)
{
var propName = col.ColumnName;
var propType = propName == nameof(ICustomViewCols.Id)
? col.DataType
: GetNullableDataType(col.DataType);
var field = tb.DefineField(propName, propType, FieldAttributes.Public);
var property = tb.DefineProperty(propName, PropertyAttributes.None, propType,
new Type[] {propType});
var propertyAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
//implement interface getter
if (propName == nameof(ICustomViewCols.HospCode)
|| propName == nameof(ICustomViewCols.Id)
|| propName == nameof(ICustomViewCols.OutDate))
{
var getMethod = typeof(ICustomViewCols).GetProperty(propName).GetGetMethod();
var currGetPropMthdBldr = tb.DefineMethod($"get_{propName}",
MethodAttributes.Public | MethodAttributes.Virtual,
propType, Type.EmptyTypes);
var getIl = currGetPropMthdBldr.GetILGenerator();
getIl.Emit(OpCodes.Ret);
tb.DefineMethodOverride(currGetPropMthdBldr, getMethod);
}
//set property getter
else
{
var currGetPropMthdBldr =
tb.DefineMethod($"get_{propName}", propertyAttr, propType,
new Type[] {propType});
var currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
property.SetGetMethod(currGetPropMthdBldr);
}
//set property setter
var currSetPropMthdBldr =
tb.DefineMethod($"set_{propName}", propertyAttr, null, new Type[] {propType});
var currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
property.SetSetMethod(currSetPropMthdBldr);
}
return tb.CreateType();
}
私有类型CreateDynamicTypeFromDataColumn(IEnumerable cols)
{
//命名
var aName=newassemblyName(“UniWeb.CustomView”);
var ab=
AssemblyBuilder.DefinedDynamicAssembly(aName,
AssemblyBuilderAccess.RunAndCollect);
var mb=
ab.DefinedDynamicModule(aName.Name+“.dll”);
var tb=mb.DefineType(
“CustomViewModel”,
类型属性(公共);
tb.AddInterfaceImplementation(typeof(ICustomViewCols));
foreach(以cols为单位的变量col)
{
var propName=col.ColumnName;
var propType=propName==nameof(ICustomViewCols.Id)
?列数据类型
:GetNullableDataType(col.DataType);
var field=tb.DefineField(propName、propType、FieldAttributes.Public);
var property=tb.DefineProperty(propName,PropertyAttributes.None,propType,
新类型[]{propType});
var propertyAttr=MethodAttributes.Public | MethodAttributes.HideBySig;
//实现接口getter
if(propName==nameof(ICustomViewCols.HospCode)
||propName==nameof(ICustomViewCols.Id)
||propName==nameof(ICustomViewCols.OutDate))
{
var getMethod=typeof(ICustomViewCols).GetProperty(propName).getMethod();
var currGetPropMthdBldr=tb.DefineMethod($“get{propName}”),
MethodAttributes.Public | MethodAttributes.Virtual,
propType,Type.EmptyTypes);
var getIl=currGetPropMthdBldr.GetILGenerator();
getIl.Emit(操作码.Ret);
tb.DefineMethodOverride(currGetPropMthdBldr,getMethod);
}
//集合属性getter
其他的
{
var currGetPropMthdBldr=
tb.DefineMethod($“get{propName}”,PropertyAtr,propType,
新类型[]{propType});
var currGetIL=currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(操作码.Ldarg_0);
currGetIL.Emit(操作码.Ldfld,字段);
currGetIL.Emit(操作码Ret);
SetGetMethod(currGetPropMthdBldr);
}
//集合属性设置器
var CURRSETPROPMTDBLDR=
tb.DefineMethod($“set{propName}”,propertyAttr,null,新类型[]{propType});
var currSetIL=currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(操作码.Ldarg_0);
currSetIL.Emit(操作码Ldarg_1);
currSetIL.Emit(操作码.Stfld,字段);
currSetIL.Emit(操作码Ret);
属性.SetSetMethod(currSetPropMthdBldr);
}
返回tb.CreateType();
}
这是我的问题的后续部分
我只使用getter更改了接口
public interface ICustomViewCols
{
int Id { get; }
DateTime? OutDate { get; }
string HospCode { get; }
}
< BR>,然后我只是实现接口的吸气剂,并将设置器视为属性设置器。
private Type CreateDynamicTypeFromDataColumn(IEnumerable<DataColumn> cols)
{
//naming
var aName = new AssemblyName("UniWeb.CustomView");
var ab =
AssemblyBuilder.DefineDynamicAssembly(aName,
AssemblyBuilderAccess.RunAndCollect);
var mb =
ab.DefineDynamicModule(aName.Name + ".dll");
var tb = mb.DefineType(
"CustomViewModel",
TypeAttributes.Public);
tb.AddInterfaceImplementation(typeof(ICustomViewCols));
foreach (var col in cols)
{
var propName = col.ColumnName;
var propType = propName == nameof(ICustomViewCols.Id)
? col.DataType
: GetNullableDataType(col.DataType);
var field = tb.DefineField(propName, propType, FieldAttributes.Public);
var property = tb.DefineProperty(propName, PropertyAttributes.None, propType,
new Type[] {propType});
var propertyAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
//implement interface getter
if (propName == nameof(ICustomViewCols.HospCode)
|| propName == nameof(ICustomViewCols.Id)
|| propName == nameof(ICustomViewCols.OutDate))
{
var getMethod = typeof(ICustomViewCols).GetProperty(propName).GetGetMethod();
var currGetPropMthdBldr = tb.DefineMethod($"get_{propName}",
MethodAttributes.Public | MethodAttributes.Virtual,
propType, Type.EmptyTypes);
var getIl = currGetPropMthdBldr.GetILGenerator();
getIl.Emit(OpCodes.Ret);
tb.DefineMethodOverride(currGetPropMthdBldr, getMethod);
}
//set property getter
else
{
var currGetPropMthdBldr =
tb.DefineMethod($"get_{propName}", propertyAttr, propType,
new Type[] {propType});
var currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
property.SetGetMethod(currGetPropMthdBldr);
}
//set property setter
var currSetPropMthdBldr =
tb.DefineMethod($"set_{propName}", propertyAttr, null, new Type[] {propType});
var currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
property.SetSetMethod(currSetPropMthdBldr);
}
return tb.CreateType();
}
私有类型CreateDynamicTypeFromDataColumn(IEnumerable cols)
{
//命名
var aName=newassemblyName(“UniWeb.CustomView”);
var ab=
AssemblyBuilder.DefinedDynamicAssembly(aName,
AssemblyBuilderAccess.RunAndCollect);
var mb=
ab.DefinedDynamicModule(aName.Name+“.dll”);
var tb=mb.DefineType(
“CustomViewModel”,
类型属性(公共);
tb.AddInterfaceImplementation(typeof(ICustomViewCols));
foreach(以cols为单位的变量col)
{
var propName=col.ColumnName;
var propType=propName==nameof(ICustomViewCols.Id)
?列数据类型
:GetNullableDataType(col.DataType);
var field=tb.DefineField(propName、propType、FieldAttributes.Public);
var property=tb.DefineProperty(propName,PropertyAttributes.None,propType,
新类型[]{propType});
var propertyAttr=MethodAttributes.Public | MethodAttributes.HideBySig;
//实现接口getter
if(propName==nameof(ICustomViewCols.HospCode)
||propName==nameof(ICustomViewCols.Id)
||propName==nameof(ICustomViewCols.OutDate))
{
var getMethod=typeof(ICustomViewCols).GetProperty(propName).getMethod();
var currGetPropMthdBldr=tb.DefineMethod($“get{propName}”),
MethodAttributes.Public | MethodAttributes.Virtual,
propType,Type.EmptyTypes);
var getIl=currGetPropMthdBldr.GetILGenerator();
getIl.Emit(操作码.Ret);
tb.DefineMethodOverride(currGetPropMthdBldr,getMethod);
}
//集合属性getter
其他的
{
var currGetPropMthdBldr=
tb.DefineMethod($“get{propName}”,PropertyAtr,propType,
新类型[]{propType});
var currGetIL=currGetPropMthdBldr.GetILGenerator();
柯尔盖蒂