就对象大小而言,如果公开的属性不表示状态而只是将其getter和setter调用委托给另一个实体,那么属性如何取代Get / Set方法会影响对象大小?
例如,请考虑以下类:
public class Person
{
Address _address = new Address();
public string AddressName
{
get{ return _address.Name; }
set { _address.Name = value; }
}
public string GetAddressName(){ return _address.Name; }
public void SetAddressName(string name){ _address.Name = name; }
}
public Address
{
public string Name { get; set; }
}
我猜测当创建一个新Person时,CLR在确定要分配多少内存时会考虑AddressName属性的潜在大小。但是,如果我暴露的是Get / Set AddressName方法,则不会分配额外的内存来满足AddressName属性。因此,为了节省内存占用,在这种情况下使用Get / Set方法会更好。但是,这将不会对Address类的Name属性产生影响,因为正在保留状态。这个假设是否正确?
答案 0 :(得分:15)
单个对象的大小不受属性,方法,事件等数量的影响。它会影响类型元数据的大小和JITted代码 - 但不会影响每个对象尺寸。那个仅受实例字段的影响。
我猜测当创建一个新Person时,CLR在确定要分配多少内存时会考虑AddressName属性的潜在大小。
没有。 仅会查看您的字段。您有一个字段(_address
),因此加上正常的对象开销是单个实例所需的所有内存。
答案 1 :(得分:5)
正如Jon已经回答的那样,对象实例的大小仅由其实例字段确定 。但是,让我更详细一点。
对象实例至少与其字段大小的总和一样大。根据字段对齐约束和CLR(公共语言运行时)布局字段的方式,可能需要考虑一些填充字节。对于引用类型,实例有两个额外的隐藏字段:同步块索引和类型引用。两者都是原生整数。在堆上,实例的最小大小为12个字节(无论它们实际需要多少空间)。
以下面的课程为例:
class X
{
byte value1;
string value2;
int value3;
long value4;
}
在32位系统上,X
的实例可能需要28个字节:
byte
的一个字节,string
的四个字节,int
long
的八个字节,如您所见,getter和setter,方法和构造函数不占用每个对象实例中的空间。相反,有一个单独的对象(您知道为Type
)维护一个方法列表(getter,setter和构造函数也是方法)并包含该类型的静态字段。您可以根据需要创建任意类型的对象实例,但对于任何给定的类型实例,只有一个Type
对象。