Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 属性或获取/设置方法对对象大小的影响_C#_Memory Management_Clr - Fatal编程技术网

C# 属性或获取/设置方法对对象大小的影响

C# 属性或获取/设置方法对对象大小的影响,c#,memory-management,clr,C#,Memory Management,Clr,就对象大小而言,如果公开的属性不表示状态,而只是将其getter和setter调用委托给另一个实体,那么属性Get/Set方法如何影响对象大小 例如,考虑以下类: public class Person { Address _address = new Address(); public string AddressName { get{ return _address.Name; } set { _address.Name = value; }

就对象大小而言,如果公开的属性不表示状态,而只是将其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/setAddressName方法,那么就不会为AddressName属性分配额外的内存。因此,为了节省内存占用,在这种情况下最好使用Get/Set方法。但是,这不会影响Address类的Name属性,因为状态被保留。此假设正确吗?

单个对象的大小不受属性、方法、事件等数量的影响。它影响类型元数据和JITted代码的大小,但不影响每个对象的大小。这只受实例字段的影响

我猜想,当创建一个新的Person时,CLR在决定分配多少内存时会考虑AddressName属性的潜在大小


不,它只看你的领域。您只有一个字段(
\u address
),因此,加上正常的对象开销,单个实例所需的所有内存都将被占用。

正如Jon已经回答的那样,对象实例的大小仅由其实例字段决定。不过,让我更详细地谈一谈

对象实例至少与其字段大小之和一样大。根据字段对齐约束和CLR(公共语言运行时)布局字段的方式,可能需要考虑一些填充字节。对于引用类型,实例有两个额外的隐藏字段:同步块索引和类型引用。两者都是本机整数。在堆上,实例的最小大小为12字节(不管它们实际需要多少空间)

以下面的类为例:

class X
{
    byte value1;
    string value2;
    int value3;
    long value4;
}
在32位系统上,
X
的实例可能需要28个字节:

  • 同步块索引和类型引用的2乘以4字节
  • 一个字节表示
    字节
  • 三个填充字节,用于对齐下一个字段
  • 对象引用字符串的四个字节
  • 另外四个字节用于
    int
  • 和八个字节的

如您所见,getter和setter、方法和构造函数并不占用每个对象实例中的空间。相反,有一个单独的对象(您称之为
Type
)维护一个方法列表(getter、setter和constructor也是方法)并包含该类型的静态字段。您可以创建任意多个类型的对象实例,但对于任何给定的类型实例,都只有一个
类型
对象。

当创建一个新人时,CLR将考虑AddressName的潜在大小
它不会,它将分配足够的空间来存储对字符串的引用。这是出于好奇吗?如果这是为了实用,我不会担心生成的IL大小的两个差异(如果有任何差异的话)。@IlyaIvanov,这是好奇,但我也在尝试为这个项目考虑性能。同意,我错了。我已经研究了属性
公共字符串AddressName
,并自动地认为
字符串
是一种支持字段。感谢您的更正请参阅杰弗里·里希特(Jeffrey Richter)的优秀著作《CLR Via C#》。每个C#程序员都应该阅读它。:)