0

I have a property with a backing field and some logic inside the setter. I wonder whether I should use the value keyword or the backing field.

Option 1:

private bool _backingField;
public bool MyProperty
{
    get => _backingField;
    set
    {
        _backingField = value;
        if(value) // <--
        {
            ...
        }
    }
}

Option 2:

private bool _backingField;
public bool MyProperty
{
    get => _backingField;
    set
    {
        _backingField = value;
        if(_backingField) // <--
        {
            ...
        }
    }
}

Which of them has better performance? Tests I have run on my machine showed no significant difference, but I am not sure my machine is enough to get the whole picture.

Note: I do realize this is probably taking micro-optimization to a whole new level of ridiculousness, but I am still curious to know if there is a definitive answer.


Edit: This question is not opinion-based, since I am asking if there is an objective difference.

Michael Haddad
  • 4,085
  • 7
  • 42
  • 82
  • 3
    I wouldn't expect a difference. – ProgrammingLlama Aug 14 '19 at 07:49
  • So are you asking if reading a variable or another makes a measurable difference? No I think not. – Steve Aug 14 '19 at 07:53
  • @Steve - Not all variables are created equal. – Michael Haddad Aug 14 '19 at 07:56
  • 2
    *"whole new level of ridiculousness"* - it's good you understand that ;). My 5 cents: in multithreading scenario using `value` is preferable, but performance is silly criteria. – Sinatr Aug 14 '19 at 07:56
  • @Sinatr - Why? What would be the consequences of using the backing field in a multithreading scenario? – Michael Haddad Aug 14 '19 at 07:58
  • I do not know who voted to close this question on an "opinion-based question" base, but I am asking if there is an ***objective*** difference that I am not noticing. – Michael Haddad Aug 14 '19 at 08:00
  • 1
    @Sipo, why? Because `value` is a parameter, field access have to be synchronized. Reading field may return another value than you just set. – Sinatr Aug 14 '19 at 08:33
  • 1
    Goto disassembly and compare translation to be sure if there is any difference or not (may differ in release/debug build too) ? – Jan Aug 14 '19 at 09:02

1 Answers1

2

Here's the IL generated with if(value) in Release mode:

.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

Note that I've added Console.WriteLine("true"); to the body of the if to prevent it to be removed by the compiler.

Now the IL with 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

The only difference is the additional call to ldfld bool ConsoleApp1.Program::_backingField in the second version, so in theory it should be a tick slower. However, that tick should be negligible small.