代码之家  ›  专栏  ›  技术社区  ›  Ed James

反射:从propertyinfo获取fieldinfo

  •  2
  • Ed James  · 技术社区  · 16 年前

    我正在使用反射进行一些动态代码生成,我遇到了这样一种情况:为了使用FieldInfo对象,我需要获取属性(如果它有)的支持字段。

    现在,我知道你可以用

    .IsDefined(typeof(CompilerGeneratedAttribute), false);
    

    在FieldInfo上发现它是否是自动生成的,所以我假设对于自动生成字段的属性有一个类似的东西?

    干杯,Ed

    3 回复  |  直到 16 年前
        1
  •  8
  •   Adam Robinson    16 年前

    这个 get_ set_ 属性方法还获取 CompilerGeneratedAttributed 适用于他们。虽然属性之间没有强耦合,但自动属性的支持字段使用了一种命名约定:

    public string Foo { get; set;}
    

    产生一个 private string <Foo>k__BackingField 成员() < > 这是名字的一部分,因为它们在IL中是合法的,但在C中不是合法的,它们与泛型无关)。

    例如,这将得到一个类中所有自动属性的列表,以及它们的支持字段:

    t.GetProperties().Where(p => 
        (p.GetGetMethod() ?? p.GetSetMethod()).IsDefined(typeof(CompilerGeneratedAttribute), false))
       .Select(p => new 
       { 
          Property = p, 
          Field = t.GetField(string.Format("<{0}>k__BackingField", p.Name),
              System.Reflection.BindingFlags.NonPublic | 
              System.Reflection.BindingFlags.Instance) 
       });
    
        2
  •  3
  •   Andrew Hare    16 年前

    由于属性的存在不一定保证支持字段的存在,因此没有内置的方法来执行此操作。

    我发现 this article 这就解释了一种方法。它包括获取属性setter的IL并对其进行解析,以寻找正在设置的字段的证据。

        3
  •  0
  •   Daniel Dolz    16 年前

    安德鲁是对的。

    实际上,属性只是指向方法的“指针”,通常是由Visual Studio或其他高级语言(大多数情况下)生成的getter/setter。

    不过,解析setter并不容易。而且,由于内部setter只是另一种普通方法,因此它们可以使用多个字段,或者根本不使用任何字段,甚至可以调用其他方法。 也许您可以为常见的场景提出一个解决方案,但是您必须解析IL字节码。