使用Reflection.Emit覆盖属性定义

我正在尝试使用Reflection.Emit(TypeBuilder)实现此模式:

public class ClassToBeProxied { public virtual object Property1 { get; set; } } public class Proxy : ClassToBeProxied { [AttributeToBeAdded] public override object Property1 { get { //do something else to return the object - ie get it from the database return null; //stub } set { //do something else to set the object - ie, save it to a database } } } 

如果我所做的只是拦截get和set方法,那么这有效:

 PropertyInfo info = typeof(ClassToBeProxied).GetProperty("Property1", BindingFlags.Public | BindingFlags.Instance); { MethodBuilder pGet = typeBuilder.DefineMethod("get_" + info.Name, MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, info.PropertyType, Type.EmptyTypes); ILGenerator pILGet = pGet.GetILGenerator(); //The proxy object pILGet.Emit(OpCodes.Ldarg_0); //The database pILGet.Emit(OpCodes.Ldfld, database); //The proxy object pILGet.Emit(OpCodes.Ldarg_0); //The ObjectId to look for pILGet.Emit(OpCodes.Ldfld, f); pILGet.Emit(OpCodes.Callvirt, typeof(MongoDatabase).GetMethod("Find", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ObjectId) }, null).MakeGenericMethod(info.PropertyType)); pILGet.Emit(OpCodes.Ret); MethodBuilder pSet = typeBuilder.DefineMethod("set_" + info.Name, MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { info.PropertyType }); ILGenerator pILSet = pSet.GetILGenerator(); pILSet.Emit(OpCodes.Ldarg_0); pILSet.Emit(OpCodes.Ldarg_1); pILSet.Emit(OpCodes.Ldarg_0); pILSet.Emit(OpCodes.Ldfld, database); pILSet.Emit(OpCodes.Call, typeof(ProxyBuilder).GetMethod("SetValueHelper", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(object), typeof(MongoDatabase) }, null)); pILSet.Emit(OpCodes.Stfld, f); pILSet.Emit(OpCodes.Ret); //Edit: Added fix newProp.SetSetMethod(pSet); newProp.SetGetMethod(pGet); } 

但我需要做的是为属性添加一个属性。 我无法弄清楚如何做到这一点。

如果我添加一个新的PropertyDefinition:

 PropertyBuilder newProp = typeBuilder.DefineProperty(info.Name, PropertyAttributes.None, info.PropertyType, Type.EmptyTypes); newProp.SetCustomAttribute(new CustomAttributeBuilder(typeof(AttributeToBeAdded).GetConstructor(Type.EmptyTypes), Type.EmptyTypes, new FieldInfo[0], new object[0])); 

然后在生成的类型上调用GetProperties(),出现两个具有相同名称的属性。 但是,如果我手动构建代码(如上例所示),并调用typeof(Proxy).GetProperties(),则只能看到一个Property(派生类属性)。 这是我需要的行为,但我似乎无法用Reflection.Emit到达那里

如果我需要添加更多信息以使问题更清楚,请告诉我。

所以答案是添加这个:

 newProp.SetSetMethod(pSet); newProp.SetGetMethod(pGet); 

查看已编辑的问题。

答案类型与http://www.gutgames.com/post/Overridding-a-Property-With-ReflectionEmit.aspx相矛盾

但它似乎工作。