Mat*_*ias 5 c# reflection.emit
有一个有一个属性的类:
public class BaseClass
{
public virtual string Property1 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在我使用一些方法覆盖创建派生类型:
[Test]
public void name ()
{
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("Test"), AssemblyBuilderAccess.RunAndSave);
var moduleBuilder = assemblyBuilder.DefineDynamicModule ("Test.dll");
var derivedBuilder = moduleBuilder.DefineType ("DerivedClass", TypeAttributes.Public, typeof (BaseClass));
const MethodAttributes methodAttributes = MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.NewSlot;
var getterOverride = derivedBuilder.DefineMethod (
"get_Property1",
methodAttributes,
typeof (string),
Type.EmptyTypes);
var getterILGenerator = getterOverride.GetILGenerator();
getterILGenerator.Emit (OpCodes.Ldnull);
getterILGenerator.Emit (OpCodes.Ret);
derivedBuilder.DefineMethodOverride (getterOverride, typeof (BaseClass).GetMethod ("get_Property1"));
var setterOverride = derivedBuilder.DefineMethod (
"set_Property1",
methodAttributes,
typeof (void),
new[] { typeof (string) });
var setterILGenerator = setterOverride.GetILGenerator ();
setterILGenerator.Emit (OpCodes.Ret);
derivedBuilder.DefineMethodOverride (setterOverride, typeof (BaseClass).GetMethod ("set_Property1"));
var derivedType = derivedBuilder.CreateType();
var props = derivedType.GetProperties (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
assemblyBuilder.Save ("Test.dll");
Assert.That (props, Has.Length.EqualTo (1));
}
Run Code Online (Sandbox Code Playgroud)
生成的类型不再包含该属性.奇怪的是,如果更改至少一个方法定义的methodAttributesto MethodAttributes.Public,则属性会再次出现.
好像是个bug?
编辑: peverify不会出错.
编辑:( Fabian Schmied的重要评论)
ECMA-335分区II,10.3.3:"如果类型通过MethodImpl覆盖继承的方法,它可以扩大或缩小该方法的可访问性."
由于规范(ECMA-335,II.10.3.3)明确允许缩小通过 MethodImpl 覆盖的方法的可见性(“显式覆盖”,由 Reflection.Emit 通过 TypeBuilder.DefineMethodOverride 表示),我相信这确实是一个Reflection 实现中的错误,应通过Microsoft Connect报告。
| 归档时间: |
|
| 查看次数: |
808 次 |
| 最近记录: |