0

我在 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) // <--
        {
            ...
        }
    }
}

他们谁有更好的表现?我在我的机器上运行的测试显示没有显着差异,但我不确定我的机器是否足以了解整个情况。

注意:我确实意识到这可能会将微优化提升到一个全新的荒谬水平,但我仍然很想知道是否有明确的答案。


编辑:这个问题不是基于意见的,因为我在问是否存在客观差异。

4

1 回答 1

2

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,所以理论上它应该慢一点。但是,该刻度应该可以忽略不计。

于 2019-08-14T09:56:14.463 回答