对成员使用简单的 1 属性是否有更多的开销(即内存,CPU,额外的IL等)?
1 “getters”和“setters”的可访问性是相同的。除了将值存储在内存中之外,getter和setter中不会发生其他逻辑。
Private CustomerId as Integer
Public CustomerName as String
VS
Private Property CustomerId as Integer
Public Property CustomerName as String
答案 0 :(得分:3)
针对以下代码运行ILDasm tool:
public class Access
{
public int NumberField;
public int NumberProp { get; set; }
}
为字段
生成以下IL.field public int32 NumberField
以下属性
.field private int32 '<NumberProp>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname instance int32
get_NumberProp() cil managed
{
// Omitting the entire IL code
} // end of method Access::get_NumberProp
.method public hidebysig specialname instance void
set_NumberProp(int32 'value') cil managed
{
// Omitting entire IL code
} // end of method Access::set_NumberProp
因此,简而言之,一旦编译器完成后,您所定义的“简单”属性的整个概念实际上并不存在 - 它会插入k_BackingField值,并创建一个访问/设置的getter / setter支持领域。请注意,即使在简单的情况下,您也可以将仅方法属性附加到get / set函数。
为了回答你的问题,是的,有更多的开销,因为get / set仍然会导致方法调用。编辑:正如联系人指出的那样,这些调用可以由JIT编译器内联,它可以将已经很小的开销减少到零。
对于编译器魔术和糖的类似研究,还要检查Lambda捕获在IL
之后的样子答案 1 :(得分:0)
开销,,如果有的话,是最小的。
正如您可能已经知道的那样,getter被转换为一个读取私有支持字段的方法,如下所示:
private int <Age>k__BackingField;
public int get_Age()
{
return <Age>k__BackingField;
}
由于此方法中没有逻辑,除了简单的return语句之外,抖动内联对此方法的调用很有可能。发生这种情况时,根本没有的开销。
即使抖动由于某种原因决定不执行内联方法调用,开销实际上也非常小,我非常怀疑你是否通过查看基准来注意到差异。