Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property with getter only vs. with getter and private setter

Tags:

c#

Are these the same?

public string MyProp { get; }

vs.

public string MyProp { get; private set; }

I mean in both versions the property can be set in its own class but is readonly for other classes?

like image 270
ChocapicSz Avatar asked Jan 27 '16 11:01

ChocapicSz


People also ask

Should setters and getters be private?

The reason for declaring the getters and setters private is to make the corresponding part of the object's abstract state (i.e. the values) private. That's largely independent of the decision to use getters and setters or not to hide the implementation types, prevent direct access, etc.

What is a getter only property?

The JavaScript strict mode-only exception "setting getter-only property" occurs when there is an attempt to set a new value to a property for which only a getter is specified.

Should getters be public or private?

In general, they should be public. If they are private they can only be called from within your class and, since you already have access to the private variables within your class, are redundant. The point of them is to allow access to these variables to other, outside, objects.

What is getter and setter properties?

What are Getters and Setters? Getters: These are the methods used in Object-Oriented Programming (OOPS) which helps to access the private attributes from a class. Setters: These are the methods used in OOPS feature which helps to set the value to private attributes in a class.


3 Answers

public string MyProp { get; } - This is introduced in C# 6.0. And such properties are called read-only auto-properties. Assignments to such members can only occur as part of the declaration or in a constructor in the same class. You can read detailed explanation about it in that MSDN article or in Jon Skeet blog. As explained in that article, such property solves four problem automatically:

  • A read-only-defined backing field
  • Initialization of the backing field from within the constructor
  • Explicit implementation of the property (rather than using an auto-property)
  • An explicit getter implementation that returns the backing field

public string MyProp { get; private set; } - This means that the property is read-only in the outside of this class, but you can change it's value inside of this class.

By the way, you can set read-only auto-properties value using new auto-initialize syntax which is again introduced in C# 6.0:

public string MyProp { get; } = "You cannot change me";

It is equal to this code for the previous versions of C#:

private readonly string myProp = "You cannot change me"
public string MyProp { get { return myProp ; } }

Or, this in C# 6.0:

public string MyProp { get; }
protected MyClass(string myProp, ...)
{
    this.MyProp = myProp;
    ...
}

is equal to this in the previous versions:

private readonly string myProp;
public string MyProp { get { return myProp; } }
protected MyClass(string myProp, ...)
{
    this.myProp = myProp;
    ...
}
like image 200
Farhad Jabiyev Avatar answered Oct 22 '22 23:10

Farhad Jabiyev


In the first one no-one can set the properties value, in the second case at least the class itself can change it. Having said this only the first one is a real "read-only"-property.

However consider combining it with a readonly-backend-field:

private readonly string field;
public string MyProp { get { return this.field; } }

Now any attemp to change the value of either the property itself or the backing-field will fail. This is identical to the syntax introduced in C#6 where the baking-field is automatically added to be reradonly:

public string MyProp { get; }

However as you already assumed for other classes both properties work same, meaning are not ment to be modified in any way.

like image 1
MakePeaceGreatAgain Avatar answered Oct 23 '22 01:10

MakePeaceGreatAgain


In C# 6.0:

public class MyClass
{
    public int MyProp1 { get; }
    public int MyProp2 { get; private set; }

    public MyClass()
    {
        // OK
        MyProp1 = 1;
        // OK
        MyProp2 = 2;
    }

    public void MyMethod()
    {
        // Error CS0200  Property or indexer 'MyClass.MyProp1' cannot be assigned to --it is read only
        MyProp1 = 1;
        // OK
        MyProp2 = 2;
    }
}

In earlier versions of C# the first property does not even compile for this reason:

Error 1 'MyClass.MyProp1.get' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.

like image 1
Andriy Buday Avatar answered Oct 23 '22 00:10

Andriy Buday