Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.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# - Fatal编程技术网

C# 设置器为空的属性是否会占用内存空间?

C# 设置器为空的属性是否会占用内存空间?,c#,C#,在下面的三个属性中,是否只有BarProp需要每个类实例4字节的内存 class Foo { int BarEmptySet { get { return 0; } set { } } int BarNoSet { get { return 0; } } int BarProp { get; set; } } 据我所知,属性实际上是“sugar”,它将类的字段包装在两个方法中:默认情况下是getter和setter 但是,它也可以描述非变量值,如常量、函数等。因此,在您

在下面的三个属性中,是否只有
BarProp
需要每个类实例4字节的内存

class Foo
{
    int BarEmptySet { get { return 0; } set { } }
    int BarNoSet { get { return 0; } }
    int BarProp { get; set; }
}

据我所知,属性实际上是“sugar”,它将类的字段包装在两个方法中:默认情况下是getter和setter


但是,它也可以描述非变量值,如常量、函数等。因此,在您的例子中,它将只实例化getter/setter函数,而不实例化所有类实例的后台字段,但最后一个实例将执行其“默认”任务-创建隐藏字段,该字段将占用每个类的内存。

,属性实际上是“sugar”,它将类的字段包装在两个方法中:默认情况下是getter和setter


但是,它也可以描述非变量值,如常量、函数等。因此,在您的示例中,它将只实例化getter/setter函数,而不实例化所有类实例的后台字段,但最后一个将执行其“默认值”职责-创建每个类占用内存的隐藏字段。

编译器只为(例如
BarProp
)生成一个备份字段。当您提供自定义的get/set实现(例如
BarEmptySet
BarNoSet
)时,不会自动生成备份字段,因此它们本身不会对对象的内存占用做出贡献

这可以通过查看生成的:

BarEmptySet:

// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

// setter
IL_0000:  nop         
IL_0001:  ret  
// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret   

// no setter is generated
// getter
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0006:  ret         

// setter
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0007:  ret    
BarNoSet:

// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

// setter
IL_0000:  nop         
IL_0001:  ret  
// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret   

// no setter is generated
// getter
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0006:  ret         

// setter
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0007:  ret    
BarProp:

// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

// setter
IL_0000:  nop         
IL_0001:  ret  
// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret   

// no setter is generated
// getter
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0006:  ret         

// setter
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0007:  ret    
//getter
IL_0000:ldarg.0
IL_0001:ldfld UserQuery+Foo.k_ubackingfield
IL_0006:ret
//塞特
IL_0000:ldarg.0
IL_0001:ldarg.1
IL_0002:stfld UserQuery+Foo.k__BackingField
IL_0007:ret

如您所见,只有
BarProp
使用
stfld
设置支持字段,并使用
ldfld
返回支持字段的值。其他人只使用文本
0

编译器只为其生成一个支持字段(例如
BarProp
)。当您提供自定义的get/set实现(例如
BarEmptySet
BarNoSet
)时,不会自动生成备份字段,因此它们本身不会对对象的内存占用做出贡献

这可以通过查看生成的:

BarEmptySet:

// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

// setter
IL_0000:  nop         
IL_0001:  ret  
// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret   

// no setter is generated
// getter
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0006:  ret         

// setter
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0007:  ret    
BarNoSet:

// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

// setter
IL_0000:  nop         
IL_0001:  ret  
// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret   

// no setter is generated
// getter
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0006:  ret         

// setter
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0007:  ret    
BarProp:

// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

// setter
IL_0000:  nop         
IL_0001:  ret  
// getter
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret   

// no setter is generated
// getter
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0006:  ret         

// setter
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+Foo.<BarProp>k__BackingField
IL_0007:  ret    
//getter
IL_0000:ldarg.0
IL_0001:ldfld UserQuery+Foo.k_ubackingfield
IL_0006:ret
//塞特
IL_0000:ldarg.0
IL_0001:ldarg.1
IL_0002:stfld UserQuery+Foo.k__BackingField
IL_0007:ret

如您所见,只有
BarProp
使用
stfld
设置支持字段,并使用
ldfld
返回支持字段的值。其他人只是使用字面的
0

为什么你会怀疑它的行为与你所建议的不同?我想说,对这个问题的早期回答证明了它的存在。一个人说IL为每个实例中的所有3个属性加载一个int;下一个人没有。我不知道这个问题的答案,所以我问。ILSpy或类似的内省工具是你的朋友。为什么你会怀疑它的行为与你所说的不同?我想说,对这个问题的早期回答证明了它的存在。一个人说IL为每个实例中的所有3个属性加载一个int;下一个人没有。我不知道这个问题的答案,所以我问。ILSpy或类似的自省工具是你的朋友。答案应该包括证据,例如指向文档的链接或类的编译IL。答案应该包括证据,例如,指向文档的链接或类的已编译IL。我认为只有在没有显式setter或getter时,它们才被称为自动属性。(所以从技术上讲,总是会为自动属性创建一个支持字段)@realbart感谢您发现了这一点,我更新了答案:)我认为只有在没有显式setter或getter的情况下,它们才被称为自动属性。(因此,从技术上讲,总是会为汽车属性创建一个支持字段)@realbart感谢您发现了这一点,我更新了答案:)