反思:从PropertyInfo获取FieldInfo

时间:2010-04-20 14:35:42

标签: c# reflection

我正在使用Reflection进行一些动态代码生成,并且我遇到了一种情况,我需要获取属性的支持字段(如果有的话)才能使用它的FieldInfo对象。

现在,我知道你可以使用

.IsDefined(typeof(CompilerGeneratedAttribute), false);

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

干杯,艾德

3 个答案:

答案 0 :(得分:8)

属性的get_set_方法也会应用CompilerGeneratedAttributed。虽然没有通过属性的强耦合,但是有一个命名约定用于auto属性的支持字段:

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) 
   });

答案 1 :(得分:3)

没有内置方法可以执行此操作,因为属性的存在不一定能保证存在后备字段。

我发现this article解释了一种做法。它涉及获取属性的setter的IL并解析它以查找正在设置的字段的证据。

答案 2 :(得分:0)

安德鲁是对的。

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

但是,解析制定者并不容易。而且,由于内部setter只是另一种vanilla方法,它们可以使用多个字段,或者根本不使用,甚至可以调用其他方法。 也许您可以为常见方案提供解决方案,但您必须解析IL字节码。