Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.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# 显式方法重写的发出隐藏属性_C#_Reflection.emit - Fatal编程技术网

C# 显式方法重写的发出隐藏属性

C# 显式方法重写的发出隐藏属性,c#,reflection.emit,C#,Reflection.emit,有一个类具有一个属性: public class BaseClass { public virtual string Property1 { get; set; } } 现在,我创建了一个带有一些方法重写的派生类型: [Test] public void name () { var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("Test"), AssemblyBui

有一个类具有一个属性:

public class BaseClass
{
  public virtual string Property1 { get; set; }
}
现在,我创建了一个带有一些方法重写的派生类型:

[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));
}
生成的类型不再包含该属性。奇怪的是,如果您将至少一个方法定义的
methodAttributes
更改为
methodAttributes.Public
,该属性会再次出现

看起来像只虫子

编辑:peverify不会给出错误

编辑:(费边·施密德的重要评论)


ECMA-335分区II,10.3.3:“如果类型通过MethodImpl重写继承的方法,它可以扩大或缩小该方法的可访问性。”

,因为(ECMA-335,II.10.3.3)明确允许缩小通过MethodImpl重写的方法的可视性(“显式重写”),由Reflection.Emit via TypeBuilder.definemethodverride表示),我相信这确实是反射实现中的一个bug,应该通过报告。

Property1是基类中的公共属性,因此它将与MethodAttributes一起显示。public是否验证生成的程序集?许多违反规范的行为都会被PEVerify捕获,但如果您只是加载代码,则不会被捕获。@CodesInChaos:PEVerify不会给出错误提示error@FabianSchmied你说服了我,我删除了我的答案。为了完整起见,我在这里重复我的评论:ECMA-335 Partition II,10.3.3:“如果类型通过MethodImpl重写继承的方法,它可以扩大或缩小该方法的可访问性。”因此,该示例似乎不会生成非法代码。