2010-04-20 80 views
2

我正在做一些使用反射的动态代码生成,并且遇到了需要获取属性的支持字段(如果有的话)以便使用它的情况FieldInfo对象。反射:从PropertyInfo获取FieldInfo

现在,我知道你可以在字段信息使用

.IsDefined(typeof(CompilerGeneratedAttribute), false); 

发现无论是自动生成的,所以我想有一个为它自动生成的字段属性类似的事情?

干杯,埃德

+0

这是我对此主题的上一个答案:http://stackoverflow.com/questions/2210309/how-to-find-out-if-a-property-is-an-auto-implemented-property-with-reflection/2210327#2210327 – jason 2010-04-20 14:53:04

回答

7

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

我不确定这是相当可靠的,是还有其他情况下这个标志将被添加到该方法中吗? – 2010-04-20 15:02:42

+0

@Ed:没有实例将它添加到与属性关联的方法中。除非将来版本的C#编译器有所改变,否则这种方法是100%可靠的。 – 2010-04-20 15:13:03

+0

我最终使用了它,它似乎很好,谢谢! – 2010-05-04 15:17:17

3

没有这样做,因为属性的存在并不一定能保证支持字段的存在没有内置的方法。

我找到了this article,它解释了一种做法。它涉及获得财产的设置者的IL并解析它寻找设置的字段的证据。

+0

是的,我明白,属性只是访问器方法的抽象,但我假设编译器会在自动生成的get上放置一个标志;方法,就像字段一样。看起来情况并非如此! – 2010-04-20 14:50:27

+0

@Ed:编译器确实将'CompilerGeneratedAttribute'应用于'get_'和'set_'方法。 – 2010-04-20 14:56:14

+0

@亚当抱歉,是的,当我读到它时,完全跳过了你答案的第一位。 – 2010-04-20 15:02:16

0

安德鲁是正确的。

实际上,属性只是方法的“指针”,当它们由Visual Studio或其他高级语言(大部分时间)生成时,通常是getters/setters。不过,解析setter并不容易。而且,由于内部制定者只是另一种香草方法,他们可以使用多个字段,或者根本不使用,甚至可以调用其他方法。 也许你可以想出一个常见场景的解决方案,但是你必须解析IL字节码。

+0

从他的问题中可以清楚地看出,他指的是自动属性,它可以可靠地链接到后台字段。 – 2010-04-20 14:49:03