【发布时间】:2012-12-28 15:52:54
【问题描述】:
我正在使用反射来映射对象。这些对象在托管代码中,但除了通过反射之外,我无法看到它们的源代码、底层结构等。所有这一切的首要目标是对象的基本内存映射(功能类似于 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() 返回的集合中。在查看 String 的引擎盖时,您会看到以下内容:
- 对象包含名为 FirstChar 的属性
- 对象包含名为 Chars 的属性
- 对象包含名为 Length 的属性
- 对象包含名为 m_stringLength 的字段
- 对象包含名为 m_firstChar 的字段
- 对象包含名为 Empty 的字段
- 对象包含名为 TrimHead 的字段
- 对象包含名为 TrimTail 的字段
- 对象包含名为 TrimBoth 的字段
- 对象包含名为 charPtrAlignConst 的字段
- 对象包含名为 alignConst 的字段
m_firstChar 和 m_stringLength 是属性 FirstChar 和 Length 的支持字段,但字符串的实际内容保存在 Chars 属性中。这是一个索引属性,可以对其进行索引以返回字符串中的所有字符,但我找不到保存字符串字符的相应字段。关于为什么会这样的任何想法?或者如何获取索引属性的支持字段?
【问题讨论】:
-
如果两个属性共享相同的支持字段,您想做什么?或者如果一个只读属性没有?还是该属性返回某种类型的类对象?
-
在任何一种情况下,结构的内存大小不只是字段的大小吗?那么您难道不只关心没有支持字段的属性吗?那些看起来像什么?
-
@Bobson- 通过使用 FieldInfo 和 PropertyInfo GetValue() 方法,我的代码中涵盖了任何引用类型,然后递归地查看它们的字段和属性。当递归链将一个对象一直映射到它的值类型时,它基本上停止了。如果两个属性共享相同的支持字段,我只想评估该支持字段的大小一次。你让我想到了另一个我想问的问题,但我很难找到答案。什么情况下属性没有后备字段?我将编辑问题以包含此内容。
-
@Chris Damour- 这是对我的问题的一个很好的改进。我相信我只关心没有支持字段的属性。很难说出它们的样子,因为我在网上找不到示例。我遇到过它,但在我自己的托管代码中重新创建它时遇到了麻烦。
-
@user1106760 这些属性是否在框架代码中?如果是这样,您能告诉我们您具体指的是哪些属性吗?
标签: c# reflection properties field memory-consumption