19

Do these statements mean the same thing?

int x { get; }
readonly int x;
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
Bob
  • 217
  • 1
  • 4
  • 11
  • don't you have to write "int x {get; private set;}" ? – jgauffin Jul 27 '10 at 15:19
  • 1
    @jgauffin: Not if the code is in an interface. – Dan Tao Jul 27 '10 at 15:22
  • 3
    I'm pretty sure you can't literally have `int x { get; }` (as an auto property), since there is no way to set it or have it do anything at all. It would have to be `int m_x; int x { get { return m_x; } }`. – Jon B Jul 27 '10 at 15:22
  • 1
    @Dan if the code is an interface then it's not read only at all. The class that implements that interface only has to expose the getter. It may or may not expose a setter. – Jon B Jul 27 '10 at 15:23
  • @Jon B: Sure. I was only pointing out to jgauffin that the code as posted is legal in a certain context. – Dan Tao Jul 27 '10 at 15:42
  • 1
    @Dan Tao: Well, I know that it's valid in interfaces. I asked since the comparison in the question is incorrect. The property declaration is only valid in interfaces and the field declaration is only valid in a class. – jgauffin Jul 27 '10 at 17:12
  • The answers to this question are out of date. See [this question](http://stackoverflow.com/questions/37496738/c-sharp-readonly-vs-get) for answers that apply to C# 6.0 – kmote Mar 13 '17 at 15:27

7 Answers7

25

In answer to your question: There is a difference between readonly and {get; }:

In int x { get; } (which won't compile as there's no way to set x - I think you needed public int x { get; private set; } ) your code can keep changing x

In readonly int x;, x is initialised either in a constructor or inline and then can never change.

John Warlow
  • 2,922
  • 1
  • 34
  • 49
  • 4
    with readonly x can only be set in the constructor or in-line. – Philip Smith Jul 27 '10 at 15:19
  • 2
    Might want to clarify that its No to 'Do these statements mean the same', but Yes to 'Is there a difference between readonly and { get; }'. Maybe the title or inline text should be changed to make it a little less confusing. – SwDevMan81 Jul 27 '10 at 15:35
  • 1
    `readonly` its important to understand that it can only be initialized in a constructor. – Stan R. Jul 27 '10 at 15:37
  • 2
    How has this got so many upvotes when int x {get;} would cause a compile time error? It isn't abstract. Shouldn't we be pointing out that this is invalid? – fletcher Jul 27 '10 at 16:38
  • `int x {get; }` generates a compile error ("must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors"). The meaning was understood, but I've updated my answer to mention the error and suggest that I think was intended. – John Warlow Jul 28 '10 at 08:23
  • 7
    In C# 6.0 a get-only property can be set in the constructor. See [this more recent question](http://stackoverflow.com/questions/37496738/c-sharp-readonly-vs-get) for a more up-to-date answer. – kmote Mar 13 '17 at 15:29
  • @kmote in C# 6.0 you can do `int x { get; } = 1;` – marsze Mar 20 '17 at 12:42
12

readonly int x; declares a readonly field on a class. This field can only be assigned in a constructor and it's value can't change for the lifetime of the class.

int x { get; } declares a readonly auto-implemented property and is, in this form, invalid (because you'd have no way whatsoever to set the value). A normal readonly property does not guarantee to return the same value every time it is called. The value can change throughout the lifetime of the class. For example:

public int RandomNumber
{
    get { return new Random().Next(100); }
}

This will return a different number everytime you call it. (Yes, this is a terrible abuse of properties).

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
Johannes Rudolph
  • 35,298
  • 14
  • 114
  • 172
3

No, the statements do not mean the same thing. The full version of the property will have a backing variable:

private int _x;

public int X
{
    get { return _x; }
}

Another method in the class could modify the backing variable, changing the value of the property:

private void SomeMethod(int someValue)
{
    _x = someValue * 5;
}

The readonly keyword only allows a member variable to be assigned in its declaration or in the constructor:

// Both of these compile

private readonly int _x = 1;

public SomeClass()
{
    _x = 5;
}

// This will not compile

private void SomeMethod(int someValue)
{
    _x = someValue * 5;
}

So a get-only property whose backing variable is marked readonly is a true read-only property.

Bryan Watts
  • 44,911
  • 16
  • 83
  • 88
3

Other answers are sorta outdated…

In newer versions of C# you can assign a default value to int x { get; } = 33; which changes things.

Basically, it gets compiled down to get-only property with a readonly private backing field. (See https://softwareengineering.stackexchange.com/q/372462/81745 for more details)

Another difference I see is that you can't use the readonly version when using interfaces as you can only define methods and properties.

jeromej
  • 10,508
  • 2
  • 43
  • 62
0

readonly keyword is making sure that these variables dont change once initialised // it is equalant to making a variable private and setting getter for it. Example.

public class PlayerAuthData 
{
    public readonly string emailId, password, userName;
    private string hello;
    public PlayerAuthData(string emailId, string password, string userName)
    {
        this.emailId = emailId;
        this.password = password;
        this.userName = userName;
    }

    public string Hello 
    {
        get { return hello; }
        set { hello = value; }
    }
}

public class AuthManager
{
    void Start()
    {
        PlayerAuthData pad = new PlayerAuthData("a@a.com", "123123", "Mr.A");
        pad.Hello = "Hi there";
        print(pad.Hello);
        print(pad.password);
        print(pad.emailId);
        print(pad.userName);
    }
}
-1

Literally, there's no big difference because you've declared x to be private (the default). You can always re-compile your class to make x different.

However, if it were public, the definition public int x { get; } allows you to later expand the definition to something like this:

int x { get {
     return DoSomeOperation();
    }
}

You can do that without breaking your clients. The implementation of the getter is private and clients call it without knowing if it is a static value or has an operation inside its get accessor.

David Gladfelter
  • 4,175
  • 2
  • 25
  • 25
-1

Propery can have backing variable that can be set using any method of that class

private int a;
public int A{get;}

public void ChangeAMethod(int value){
    a=value;
}

However readonly fields can only be assigend in constructor or in-line.

Akshay
  • 7
  • 1
  • 1
    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](/help/how-to-answer). – Community Feb 10 '23 at 10:37