Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Reflection.Emit重写属性定义_C#_Reflection.emit - Fatal编程技术网

C# 使用Reflection.Emit重写属性定义

C# 使用Reflection.Emit重写属性定义,c#,reflection.emit,C#,Reflection.emit,我正在尝试使用Reflection.Emit(TypeBuilder)实现此模式: 如果我所做的只是截取get和set方法,那么这是可行的: PropertyInfo info = typeof(ClassToBeProxied).GetProperty("Property1", BindingFlags.Public | BindingFlags.Instance); { MethodBuilder pGet = typeBuilder.DefineMethod("get_" + in

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

如果我所做的只是截取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(),则只有一个属性(派生类属性)可见。这是我需要的行为,但我似乎无法通过反射达到目的。发射


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

因此答案是添加以下内容:

newProp.SetSetMethod(pSet);
newProp.SetGetMethod(pGet);
请参见已编辑的问题

答案有点矛盾


但是它似乎是有效的。

hi@Joe Enzminger,你能详细说明覆盖getter方法的最简单方法是什么吗?提供的代码不完整,我在理解你在每个步骤中所做的事情时发现了一些问题。感谢大家看一下代码片段。非常感谢,关键不在于定义属性,而在于get和set函数
newProp.SetSetMethod(pSet);
newProp.SetGetMethod(pGet);