-1

Can anyone please help me understand the internal process of how C# class fields work? And how class properties (with getters and setters) work?

While comparing performance I found properties are a lot slower to access than fields. So what is the reason behind this?

  • 4
    There are plenty of resources online (that you can google) that discuss the pros and cons of C# properties over fields. – MetaFight Dec 13 '17 at 12:17
  • 2
    I edited the question for clarity. I believe I retained the original intention of the OP, but if anyone thinks I overreached please feel free to revert. – MetaFight Dec 13 '17 at 12:20
  • @MetaFight, I slightly adjusted your edit, to reflect the fact that property access is slower than direct field access. – David Arno Dec 13 '17 at 13:19
  • @DavidArno, yeah, I thought the OP had erroneously observed that there wasn't a performance difference between the two. But, after reviewing the original post it could have been interpreted either way. Your edit adds to overall clarity, though, so cheers :) – MetaFight Dec 13 '17 at 13:34
  • 1
    @MetaFight, ironically I'm not now so sure. As Paul K points out in his answer, the property could be optimised away by the JIT, so the OP may have observed no speed difference. – David Arno Dec 13 '17 at 13:36
7

Properties and fields are two fundamentally different concepts. Fields are mere variables defined in your class. They are - more or less - accessed directly. You can see this in the IL code for setting a member variable

memberVariable = "Test";

yields the following IL code

IL_0000:  ldarg.0     
IL_0001:  ldstr       "Test"
IL_0006:  stfld       UserQuery.field

Properties at the other hand are more functions than variables, although they are accessed like variables (from C# code, not from IL). There is much more going on in the background.

The auto-property

public string AutoProperty { get; set; }

and setting it

AutoProperty = "Hallo";

will yield the following IL code.

Property:

get_AutoProperty:
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery.<AutoProperty>k__BackingField
IL_0006:  ret         

set_AutoProperty:
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery.<AutoProperty>k__BackingField
IL_0007:  ret  

Setting the property:

IL_0000:  ldarg.0     
IL_0001:  ldstr       "Hallo"
IL_0006:  call        UserQuery.set_AutoProperty

As you can see, the compiler generates a method set_AutoProperty with the implicit backing field UserQuery.<AutoProperty>k__BackingField.

Wny you should really use properties

While auto-properties are of virtually no more use than public fields, explicit properties have their merits, since you are able to decouple the internals of a class from its public interface. See the following temperature implementation

class Temperature
{
    double _kelvin = 0;

    public double Fahrenheit 
    {
        get
        {
            return _kelvin*9.0/5.0 - 459.67;
        }
        set
        {
            _kelvin = (value + 459.67) * 5.0/9.0;
        }
    }

    public double Celsius
    {
        get
        {
            return _kelvin - 273.15;
        }
        set
        {
            _kelvin = value + 273.15;
        }
    }
}

Your client does not know about the internal representation of the temperature, it only knows that it can get the temperature in °Fahrenheit or °Celsius, depending on its needs. If it's convenient for you, the internal representation may change without changing the public interface. At the other hand, if you decised to expose the temperature in Kelvin as a public field, you'll have to stick with it or risk breakting client code.

On the performance of properties

According to the answers to this question, the compiler will inline the calls to set_AutoProperty and get_AutoProperty if this is possible. This is most likely the reason why you did not find any difference between those two. Unfortunately I have not been able to replicate the compiler behavior in LINQPad.

|improve this answer|||||
  • AutoProperties have one very important trait that fields don't, however - they are easier to debug. Just being able to slap a breakpoint on that Set and check the call stack to see who is setting it to that weird value is more than enough for me to justify using them. Oh, and you can set different permission levels for the get and the set (as in, public get, private set, for example). – T. Sar Dec 15 '17 at 16:04
  • @T.Sar this holds only if you consider public fields as an option, but is no argument for auto-properties whatsoever. – Paul Kertscher Dec 15 '17 at 16:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.