14

C# 6 added auto-property initializers and so we can do

private List<LinearLayout> layouts1 { get; } = new List<LinearLayout>();

Is this better or worse than

private readonly List<LinearLayout> layouts2 = new List<LinearLayout>();

(N.B. this is related to the 2011 question .NET Properties - Use Private Set or ReadOnly Property?, but that includes a public getter alongside a private setter. Here I only have a private getter.)

3
  • Better or worse by what measure? Also, I don't believe they are entirely interchangable (in your case they are). There are situations where you could set a readonly property to something you would never be able to with an auto property with only a get.
    – Becuzz
    Commented Jun 12, 2018 at 14:17
  • 1
    What ever is the point of a private getter or setter (auto-generated or not) of a private field given no field transformation?
    – radarbob
    Commented Jun 12, 2018 at 15:26
  • @radarbob, perhaps to represent a contract to myself, in this case to not set the field
    – dumbledad
    Commented Jun 13, 2018 at 7:41

3 Answers 3

19

If you take a look here, you'll see that the following code:

class Example
{
   private List<LinearLayout> layouts1 { get; } = new List<LinearLayout>();
}

Is lowered by the compiler to:

internal class Example
{
    private readonly List<LinearLayout> <layouts1>k__BackingField = new List<LinearLayout>();

    private List<LinearLayout> layouts1
    {
        get
        {
            return <layouts1>k__BackingField;
        }
    }
}

and the property gets further lowered to a get_layouts1() method.

In other words, auto-property initializers are pure syntactic sugar. They provide a means of using auto-properties, whilst still allowing the backing field to be initialised.

So from a mutability point of view, there's no difference between them at all. Both provide read-only access to a list that is initialised when an instance of the class is created.

It's possible that it creates a slight performance overhead as the method must be called to obtain the list reference, but it's likely that the CLR JIT optimises the method away and just accesses the field directly.

The most obvious use for private properties is for lazy loading/deferred execution purposes. There are other uses, but as a guideline, they are often pointless "noise". I'd not go so far as to say that using a private property is worse than just using a field, but I'd advise just using a read-only field for most cases.

2
  • 4
    Thanks - I'm not sure the only real use is lazy loading or deferred execution, some of the other answers to that question are interesting, for example EricLippert uses them for debugging (here), JaredPar and others for calculated values (here), MattGreer as contracts with himself (here), and YohanesNurcahyo to improve readability (here)
    – dumbledad
    Commented Jun 13, 2018 at 8:11
  • 1
    @dumbledad, good point. I have tried to rephrase that last part to reflect that as I'm not going to argue with the likes of Eric Lippert! :)
    – David Arno
    Commented Jun 13, 2018 at 8:23
0

In this case they would function almost identically. There is one subtlety that would make the private property less than ideal:

  • The bytecode would access the List<LinearLayout> through a getter function. However, as soon as the bytecode is recompiled for your environment (which C# has done for a long time), the getter function would be optimized out, so not a real problem.

If they are used identically, there won't be any practical difference.

5
  • To be crystal-clear, readonly doesn't make the list immutable; it merely prevents someone from assigning a different list to the member variable. Commented Jun 12, 2018 at 15:06
  • 1
    @BerinLoritsch, "You can set a private property". This is incorrect. There is no "implicit private setter". The setter has to be explicitly specified with set. private List<LinearLayout> layouts1 { get; } is read-only.
    – David Arno
    Commented Jun 12, 2018 at 18:17
  • Going by codebetter.com/derikwhittaker/2014/11/18/…, @DavidArno seems to be correct. When you declare a property with { get; }, there is no private setter at all. However, C# 6 made it so you can change the value of a get-only auto-implemented property within a constructor, by assigning to the backing field. You code this as though you were assigning to the property. In any case, the backing field is readonly, so the statement that "unlike the readonly private field, the private property is mutable" is incorrect. Commented Jun 12, 2018 at 20:12
  • 1
    @BerinLoritsch I just did a test and @DavidArno & @TannerSwett are correct. If I later try to set layouts1 I get the error "Property or indexer 'MainActivity.layouts1' cannot be assigned to -- it is read only" and if I try to set layouts2 I get the error "A readonly field cannot be assigned to (except in a constructor or a variable initializer)" so there is no implicit private setter, at least none one can use.
    – dumbledad
    Commented Jun 13, 2018 at 6:48
  • I have removed the misremembered information. Commented Jun 13, 2018 at 14:04
-1

This answer does not exactly add any more than some clarity to the accepted answer, but: private properties aren't suggested. If the field is purely private then just use a field. Properties are there to encapsulate the fields. If later you want to make the field public (or internal), you can introduce a property that returns it; and also get the ability to separately define the access level of the setter (i.e. internal List Layouts1 { get; private set; }). And obviously also, the property getter and setter bodies can be expanded to contain any other code as well. (So use the private field since it's purely a private instance member.)

2
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Aug 15, 2023 at 20:22
  • The private property adds no benefits, and clutters the code more. Commented Aug 24, 2023 at 18:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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