使用反射来确定哪些字段是来头房产领域(Using Reflection to determine w

2019-07-18 04:51发布

我使用反射来绘制出对象。 这些对象是在托管代码,但我不了解其源代码,底层结构等不是通过反射其他。 所有这一切的首要目标是对象的一个基本的存储器映射(在功能上类似SOS.dll DumpObject!ObjSize命令)。 因此,我试图确定哪些成员正在“重复计算”既是一个字段和属性。

例如:

public class CalendarEntry
{
    // private property 
    private DateTime date { get; set;}

    // public field 
    public string day = "DAY";
}

当映射显示:

  • 字段
    • k__BackingField
  • 属性
    • 日期

凡为这样的类:

public class CalendarEntry
{
    // private field 
    private DateTime date;

    // public field 
    public string day = "DAY";

    // Public property exposes date field safely. 
    public DateTime Date
    {
        get
        {
            return date;
        }
        set
        {
                date = value;
        }
    }
}

当映射显示:

  • 字段
    • 日期
  • 属性
    • 日期

乍一看没有什么可以告诉你的是, Date属性的“支持字段”是字段中指定date 。 我试图避免这种情况下的两倍计算日期,因为这会给我一个坏的内存大小近似。

更重要的是混淆/复杂的是我遇到的情况,其属性并不总是有将通过上市的对应字段Type.GetFields()方法,所以我不能只是完全无视所有属性。

关于如何确定从返回的集合在一个领域任何想法Type.GetFields()基本上是一些相应属性的支持字段从返回Type.GetProperties()

编辑-我已经很难确定什么样的条件的属性不会有相应的字段在集合中列出从返回Type.GetFields() 是任何人都熟悉这样的条件?

编辑2 -我发现当一个属性的支持字段将不包括从返回的集合中的一个很好的例子Type.GetFields() 。 当一个字符串的引擎盖下看你具备以下条件:

  • 对象包含属性命名FirstChar
  • 对象包含属性命名字符数
  • 对象包含属性命名长度
  • 对象包含字段命名m_stringLength
  • 对象包含字段命名m_firstChar
  • 对象包含字段名为空
  • 对象包含字段命名TrimHead
  • 对象包含字段命名TrimTail
  • 对象包含字段命名TrimBoth
  • 对象包含字段命名charPtrAlignConst
  • 对象包含字段命名alignConst

m_firstCharm_stringLength是属性的支持领域FirstCharLength ,但字符串的实际内容的字符数属性举行。 这是一个可以被索引,以返回字符串中所有字符的索引属性,但我找不到持有字符串的字符的对应字段。 为什么说是有什么想法? 或如何获得索引属性的支持字段?

Answer 1:

一个属性的支持字段的名称是一个编译器的实现细节,总是可以改变未来,即使你找出模式。

我想你已经打在回答你的问题: 忽略所有属性

请记住,一个属性是变相只是一个或两个功能。 一个属性将仅具有一个编译器生成支持字段时由源代码特别要求。 例如,在C#:

public string Foo { get; set; }

但一类的创建者不需要使用编译器生成的属性是这样的。 例如,属性可能会得到一个恒定值,多个属性可能获取/设置的比特字段的不同部分,依此类推。 在这种情况下,你不会希望看到一个单一的支持字段为每个属性。 它也可以忽略这些属性。 您的代码不会错过任何实际的数据。



Answer 2:

你完全可以无视所有属性。 如果属性没有支持字段,那么它根本不消耗任何内存。

此外,除非你愿意(尝试)解析CIL,你将无法得到这样的映射。 考虑以下代码:

private DateTime today;

public DateTime CurrentDay
{
    get { return today; }
}

你怎么能指望弄清楚,存在一定的关系today场和CurrentDay财产?

编辑:关于你最近的问题:

如果您有属性,它包含类似的代码return 2.6; ,则值不会在任何位置保持,即恒定在代码直接嵌入。

关于stringstring是由CLR以一种特殊的方式来处理。 如果你试图反编译其索引,你会发现它是由CLR实现。 对于这些少数特殊类型( string ,数组, int ,...),你不能看着他们的领域找到自己的尺寸。 对于所有其他类型,你可以。



Answer 3:

为了回答您的其他问题:什么情况下性能不会有备份领域?

public DateTime CurrentDay
{
    get { return DateTime.Now; }
}

或特性可以使用备份字段/类的任何其它数量的

public string FullName 
{
    get {return firstName + " " + lastName;}
}


文章来源: Using Reflection to determine which Fields are backing fields of a Property