如何使用TypeBuilder生成带属性的C#接口?
动态创建带属性的接口问题解决方法
问题背景
需求是用TypeBuilder动态创建包含属性的接口,目标接口示例如下:
public interface ISample { public decimal Amount { get; set; } public decimal Price { get; set; } public double Quantity { get; set; } }
现有代码可编译运行,但生成的接口类型无法识别到任何属性,核心代码如下:
创建TypeBuilder的方法
private static TypeBuilder GetInterfaceTypeBuilder(string TypeName) { var typeSignature = TypeName; var an = new AssemblyName(typeSignature); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); TypeBuilder tb = moduleBuilder.DefineType(typeSignature, TypeAttributes.Interface | TypeAttributes.Abstract); return tb; }
创建属性的方法
private static void CreateInterfaceProperty(TypeBuilder tb, string propertyName, Type propertyType) { PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); }
编译接口类型的方法
public static Type CompileInterfaceType(string TypeName, List<Field> yourListOfFields) { TypeBuilder tb = GetTypeBuilder(TypeName); // 原代码存在方法名调用错误 // 假设yourListOfFields包含Field对象,有FieldName(string)和FieldType(Type)属性 foreach (var field in yourListOfFields) { CreateInterfaceProperty(tb, field.FieldName, field.FieldType); } Type objectType = tb.CreateType(); return objectType; }
问题原因与解决方法
问题核心在于:接口的属性本质是一对抽象的get/set方法,原代码仅创建了PropertyBuilder,但未定义属性对应的getter和setter方法,导致反射无法识别到属性。
修改后的创建属性方法
private static void CreateInterfaceProperty(TypeBuilder tb, string propertyName, Type propertyType) { // 定义属性 PropertyBuilder propertyBuilder = tb.DefineProperty( propertyName, PropertyAttributes.None, propertyType, null); // 定义get方法:public abstract [Type] get_[PropertyName]() MethodBuilder getMethodBuilder = tb.DefineMethod( $"get_{propertyName}", MethodAttributes.Abstract | MethodAttributes.Public | MethodAttributes.Virtual, propertyType, Type.EmptyTypes); // 定义set方法:public abstract void set_[PropertyName]([Type] value) MethodBuilder setMethodBuilder = tb.DefineMethod( $"set_{propertyName}", MethodAttributes.Abstract | MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), new Type[] { propertyType }); // 将get/set方法关联到属性 propertyBuilder.SetGetMethod(getMethodBuilder); propertyBuilder.SetSetMethod(setMethodBuilder); }
修正编译方法的调用错误
public static Type CompileInterfaceType(string TypeName, List<Field> yourListOfFields) { TypeBuilder tb = GetInterfaceTypeBuilder(TypeName); foreach (var field in yourListOfFields) { CreateInterfaceProperty(tb, field.FieldName, field.FieldType); } return tb.CreateType(); }
关键说明
- 接口中的属性必须对应抽象的get和set方法,这是.NET接口属性的底层实现逻辑
- 方法命名必须遵循规范:
get_PropertyName和set_PropertyName - 方法属性需设置为
Abstract | Public | Virtual,符合接口成员的访问规则
内容的提问来源于stack exchange,提问作者Brian Wheatley
相关产品推荐
相关产品推荐

