nbe*_*e11 10 c# reflection field properties memory-consumption
我正在使用反射来绘制对象.这些对象在托管代码中,但除了通过反射之外,我无法看到它们的源代码,底层结构等.所有这一切的首要目标是对象的基本内存映射(类似于SOS.dll DumpObject和!ObjSize命令的功能).因此,我试图确定哪些成员被"重复计算"为一个字段和一个属性.
例如:
public class CalendarEntry
{
// private property
private DateTime date { get; set;}
// public field
public string day = "DAY";
}
Run Code Online (Sandbox Code Playgroud)
映射时显示:
像这样的一个类:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
映射时显示:
乍一看,没有什么可以告诉你,该Date属性的"支持字段"是名为的字段date.我试图在这种情况下避免两次计算日期,因为这会给我一个糟糕的内存大小近似值.
更令人困惑/复杂的是我遇到过这样的情况:属性并不总是有一个相应的字段,这个字段将通过该Type.GetFields()方法列出,所以我不能完全忽略所有属性.
关于如何确定返回的集合中的字段Type.GetFields()是否基本上是从某些相应属性返回的支持字段的任何想法Type.GetProperties()?
编辑 - 我无法确定属性在返回的集合中列出的相应字段的条件Type.GetFields().有人熟悉这种情况吗?
编辑2-我找到了一个很好的例子,说明属性的支持字段何时不会包含在从中返回的集合中Type.GetFields().在String的引擎盖下查看时,您有以下内容:
该m_firstChar和m_stringLength是属性的支持领域FirstChar和Length,但字符串的实际内容的字符数属性举行.这是一个索引属性,可以索引它以返回String中的所有字符,但是我找不到包含字符串字符的相应字段.有什么想法吗?或者如何获取索引属性的支持字段?
属性的支持字段的名称是编译器实现细节,即使您找出模式,也可以在将来进行更改.
我想你已经找到了问题的答案:忽略所有属性.
请记住,一个属性只是伪装的一两个功能.在源代码特别请求时,属性将只有编译器生成的支持字段.例如,在C#中:
public string Foo { get; set; }
Run Code Online (Sandbox Code Playgroud)
但是类的创建者不需要像这样使用编译器生成的属性.例如,属性可能获得常量值,多个属性可能获取/设置位字段的不同部分,依此类推.在这些情况下,您不希望看到每个属性的单个支持字段.忽略这些属性是可以的.您的代码不会遗漏任何实际数据.