简体   繁体   English

反思:从PropertyInfo获取FieldInfo

[英]Reflection: Get FieldInfo from PropertyInfo

I'm doing some dynamic code generation using Reflection, and I've come across a situation where I need to get the backing field of a property (if it has one) in order to use its FieldInfo object. 我正在使用Reflection进行一些动态代码生成,并且我遇到了一种情况,我需要获取属性的支持字段(如果有的话)才能使用它的FieldInfo对象。

Now, I know you can use 现在,我知道你可以使用

.IsDefined(typeof(CompilerGeneratedAttribute), false);

on a FieldInfo to discover whether it's autogenerated, so I assume there's a similar thing for Properties which auto-generate fields? 在FieldInfo上发现它是否是自动生成的,所以我假设属性类似于自动生成字段?

Cheers, Ed 干杯,艾德

The get_ and set_ methods for properties also get the CompilerGeneratedAttributed applied to them. 属性的get_set_方法也会应用CompilerGeneratedAttributed While there is no strong coupling through attributes, there is a naming convention used for the backing fields of an auto property: 虽然通过属性没有强耦合,但是有一个命名约定用于auto属性的支持字段:

public string Foo { get; set;}

Produces a private string <Foo>k__BackingField member (the < and > here are part of the name, as they're legal in IL but not in C#; they have nothing to do with generics). 生成一个private string <Foo>k__BackingField成员( <>这里是名称的一部分,因为它们在IL中合法但在C#中不合法;它们与泛型无关)。

As an example, this will get a list of all of the auto properties in a class, along with their backing fields: 例如,这将获得一个类中所有自动属性的列表,以及它们的支持字段:

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

There is no built-in method for doing this since the presence of a property does not necessarily guarantee the presence of a backing field. 没有内置的方法来执行此操作,因为属性的存在不一定保证存在后备字段。

I found this article which explains one way of doing it. 我发现这篇文章解释了一种做法。 It involves getting the IL of the property's setter and parsing it looking for evidence of a field being set. 它涉及获取属性的setter的IL并解析它以查找正在设置的字段的证据。

Andrew is right. 安德鲁是对的。

Actually, a property is just a "pointer" to methods, usually getters/setters when they are generated by Visual Studio or other high level language (most of the time). 实际上,属性只是方法的“指针”,通常是由Visual Studio或其他高级语言(大多数时候)生成的getter / setter。

Parsing the setter is not easy, though. 但是,解析二传手并不容易。 And, since internally setters are just another vanilla methods, they can use more than one fields, or none at all, or even call another methods. 而且,由于内部setter只是另一种vanilla方法,它们可以使用多个字段,或者根本不使用,甚至可以调用其他方法。 Perhaps you can come up with a solution for the common scenarios, but you have to parse the IL bytecode. 也许您可以为常见方案提供解决方案,但您必须解析IL字节码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM