属性 setter 中的支持字段与 "value" 关键字
Backing field vs "value" keyword in property setter
我有一个 属性,其中有一个支持字段和 setter 中的一些逻辑。我不知道我应该使用 value
关键字还是支持字段。
选项 1:
private bool _backingField;
public bool MyProperty
{
get => _backingField;
set
{
_backingField = value;
if(value) // <--
{
...
}
}
}
选项 2:
private bool _backingField;
public bool MyProperty
{
get => _backingField;
set
{
_backingField = value;
if(_backingField) // <--
{
...
}
}
}
他们谁的表现更好?我在我的机器上进行的测试 运行 显示没有显着差异,但我不确定我的机器是否足以获取完整图片。
注意:我确实意识到这可能将微优化带到了一个全新的荒谬水平,但我仍然很想知道是否有明确的答案。
编辑: 这个问题不是基于意见的,因为我问的是是否存在 objective 差异。
这是在 Release 模式下使用 if(value)
生成的 IL:
.method public hidebysig specialname instance void
set_MyProperty(bool 'value') cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld bool ConsoleApp1.Program::_backingField
IL_0007: ldarg.1
IL_0008: brfalse.s IL_0014
IL_000a: ldstr "true"
IL_000f: call void [mscorlib]System.Console::WriteLine(string)
IL_0014: ret
} // end of method Program::set_MyProperty
请注意,我已将 Console.WriteLine("true");
添加到 if
的正文中,以防止它被编译器删除。
现在 IL if (_backingField)
:
.method public hidebysig specialname instance void
set_MyProperty(bool 'value') cil managed
{
// Code size 26 (0x1a)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld bool ConsoleApp1.Program::_backingField
IL_0007: ldarg.0
IL_0008: ldfld bool ConsoleApp1.Program::_backingField
IL_000d: brfalse.s IL_0019
IL_000f: ldstr "true"
IL_0014: call void [mscorlib]System.Console::WriteLine(string)
IL_0019: ret
} // end of method Program::set_MyProperty
唯一的区别是在第二个版本中额外调用了ldfld bool ConsoleApp1.Program::_backingField
,所以理论上应该慢一点。但是,那个滴答声应该可以忽略不计。
我有一个 属性,其中有一个支持字段和 setter 中的一些逻辑。我不知道我应该使用 value
关键字还是支持字段。
选项 1:
private bool _backingField;
public bool MyProperty
{
get => _backingField;
set
{
_backingField = value;
if(value) // <--
{
...
}
}
}
选项 2:
private bool _backingField;
public bool MyProperty
{
get => _backingField;
set
{
_backingField = value;
if(_backingField) // <--
{
...
}
}
}
他们谁的表现更好?我在我的机器上进行的测试 运行 显示没有显着差异,但我不确定我的机器是否足以获取完整图片。
注意:我确实意识到这可能将微优化带到了一个全新的荒谬水平,但我仍然很想知道是否有明确的答案。
编辑: 这个问题不是基于意见的,因为我问的是是否存在 objective 差异。
这是在 Release 模式下使用 if(value)
生成的 IL:
.method public hidebysig specialname instance void
set_MyProperty(bool 'value') cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld bool ConsoleApp1.Program::_backingField
IL_0007: ldarg.1
IL_0008: brfalse.s IL_0014
IL_000a: ldstr "true"
IL_000f: call void [mscorlib]System.Console::WriteLine(string)
IL_0014: ret
} // end of method Program::set_MyProperty
请注意,我已将 Console.WriteLine("true");
添加到 if
的正文中,以防止它被编译器删除。
现在 IL if (_backingField)
:
.method public hidebysig specialname instance void
set_MyProperty(bool 'value') cil managed
{
// Code size 26 (0x1a)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld bool ConsoleApp1.Program::_backingField
IL_0007: ldarg.0
IL_0008: ldfld bool ConsoleApp1.Program::_backingField
IL_000d: brfalse.s IL_0019
IL_000f: ldstr "true"
IL_0014: call void [mscorlib]System.Console::WriteLine(string)
IL_0019: ret
} // end of method Program::set_MyProperty
唯一的区别是在第二个版本中额外调用了ldfld bool ConsoleApp1.Program::_backingField
,所以理论上应该慢一点。但是,那个滴答声应该可以忽略不计。