Search code examples
c#propertiesprivateencapsulation

When to use private properties (with no special logic)


Recently I've been reading some threads about always using properties instead of public fields in C#, but what about private properties? Of course, there are a few threads about it, but they almost always talked about additional logic / lazy-loading etc.

Let's say I have a readonly field that will be accessed all around the Program class, but (at least for now) it's not used anywhere else:

static class Program
{
    private static readonly Canvas canvas = new Canvas(100, 30);
    // Canvas is like the main class of my game, there can be only one instance of it

    static void Main()
    {
        // ...
        canvas.DoSomething();
        // ...
    }

    // ...
    // Many other references to "canvas" here
}

or should I do something like this:

private static Canvas Canvas { get; } = new Canvas(100, 30);

The second option means that I can easily make this public, which I might or might not do in the future. And what about other private fields? Are there any rules or guidelines about what should be a private property or not? Or should I declare everything as a field because it's private (although it feels public-ish)?

Just for clarification:

  • I'm not making a reusable library, just a console game;
  • I'm not going to implement any logic about getting / setting the value;
  • I'm writing the Canvas class myself, it's not external.

Solution

  • Using private properties is useless because only the current class members have access to it and it is read and write.

    Unless you want only to initialize it in constructors or at declaration level, and disallow the write in others methods, so you can write:

    private MyField { get; }
    

    The difference between declaring a readonly field and such property is that the property read accessor is a method so it causes a CPU proc call tick consuming on each access, that does not require a readonly property.

    So it is a matter of speed performance else it is the same finality.

    Here is a test class:

    public class Test
    {
      private readonly int MyField = 10;
      private int MyProperty { get; }
      public Test()
      {
        MyProperty = 10;
      }
      public void Method()
      {
        var value1 = MyField;
        var value2 = MyProperty;
      }
    }
    

    And here the IL code generated by the compiler:

    // int myField = MyField;
    IL_0001: ldarg.0
    IL_0002: ldfld int32 ConsoleApp.Test::MyField
    IL_0007: stloc.0
    
    // int myProperty = MyProperty;
    IL_0008: ldarg.0
    IL_0009: call instance int32 ConsoleApp.Test::get_MyProperty()
    IL_000e: stloc.1
    

    With a readonly field there is only a load of the value into the stack, that the CLR replaces by a target processor load into a register instruction, that is fast (MOV).

    With a property there is a .NET method call, that the CLR replaces by a target processor procedure call instruction, that eats lots of CPU ticks as well as the return (CALL/RET).

    .method private hidebysig specialname instance int32 get_MyProperty () cil managed 
    // return MyProperty;
    IL_0000: ldarg.0
    IL_0001: ldfld int32 ConsoleApp.Test::'<MyProperty>k__BackingField'
    IL_0006: ret
    

    So a property needs many more CPU cycles than a readonly field, but the result is the same in terms of operation (I will say a wrong value because I don't remember for x486 and it is old, but imagine it may be ~5 to 20 times slower to have an idea).

    Therefore it is a matter of preference if speed is not critical. You can change to public without problem, the high level design remains the same: there is no difference else the speed and the look.

    That said, remember that public properties are required for the Visual Studio designer, components design and serialization for example. So using properties may be a gain of time as well as be more smart.

    https://superuser.com/questions/643442/latency-of-cpu-instructions-on-x86-and-x64-processors