9

I've just gotten started learning c#, and I'm struggling a bit with the getter and setter shorthand.

As I understand it, the two methods below are equivalent. Is this correct?

//Method 1
public string name { get; set; }

//Method 2
private string name
public string getName() { return name;}
public string setName(string newName) { this.name = newName; }

Secondly, how does this work if we wanted different access modifiers on the getter/setter and the instance variable. The following code errors, telling me that the accessor must be more restrictive than the property and that I can't specify modifiers for bother accessors. Can somebody please clarify?

private int maxTime { public get; public set; }

EDIT: To clarify, I have no specific goal, only to understand. I don't understand what this shorthand notation does. In other languages I've had private instance variables and used public getters and setters to manage these instance variables. It allows this if I write out the methods on my own, but not with this shorthand notation. Why is this?

EDIT2: One last question to check my understanding. Both of the code snippets below use properties to manage the maxTime variable. The only difference between the two is style. Is this correct?

private int maxTime;
public int MaxTime{ get; set; }

vs

private int maxTime;

public int MaxTime
{
    get { return maxTime; }
    set { maxTime= value; }
}
JShell
  • 624
  • 2
  • 7
  • 22
  • 2
    Why would you want public getter/setter on a private variable? – eddie_cat Jul 16 '15 at 14:42
  • 1
    No, those two approaches are not the same. Explain what you want to do, not only what code you ended up with. – CodeCaster Jul 16 '15 at 14:43
  • You can't do _private int maxTime { public get; public set; }_ as the outer access for the property (NOT a variable!) is more restrictive than the inner. You could do _public int maxTime { private get; set; }_ - NOTE public modifier not required for set – PaulF Jul 16 '15 at 14:44
  • The most limited scope takes precedence, as clearly stated by the error, and fairly intuitively. `public` as the `get`/`set` level is redundant, always; a `public` property with a `protected` or `private` `set` can be useful. There are a number of ways to do properties in C#, though, so perhaps just stating what you intend to do, and don't get bogged down comparing it to other languages and functionality equivalents, would garner a better answer. – Grant Thomas Jul 16 '15 at 14:45
  • You shouldn't care about access modifier for the hidden instance variable. Its simply unreachable. That there is an actual hidden instance variable is just an implementation detail. – Ralf Jul 16 '15 at 14:47

5 Answers5

19

Instead of the wrong private int maxTime { public get; public set; }, you can write a property that will populate a private field:

private int maxTime;

public int MaxTime
{
    get { return maxTime; }
    set { maxTime = value; }
}

This is useful when you want to apply logic when getting or setting the value of maxTime. if not, a simple shorthand property will do:

public int MaxTime { get; set; }

You can create a property that have a public getter but a private setter, like this:

public int MaxTime { get; private set; }

This is useful for readonly properties, and usually the property is populated in the constructor of the class.

You can even create a property where the setter is public but the getter is private, though I can't imagine any scenario this would be useful. Moreover, code standards claim that such a thing should be a method, not a property. (read this)

public int MaxTime { private get; set; }

The answer your question in edit 2 is no.

the first code never change the private int maxTime, while the second one does. However, if inside your class you only use the property MaxTime, then they are functionally equivalent.

Update:

Since c# 6 you can write shorthand properties without a setter:

public int MaxTime {get;}

These properties can only be initialized in the constructor, or hard coded like this: (also a new feature of c# 6)

public int MaxTime {get;} = DateTime.Now;

This is useful for immutable properties (unlike readonly properties, the value of such a property can not change even inside the hosting class once initialized.

Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • So in your second code snippet, are both the get and set public? – JShell Jul 16 '15 at 14:51
  • Yes. Unless a more restrictive access modifier is specified to the getter or setter, they will both have the property access modifier. – Zohar Peled Jul 16 '15 at 14:54
  • So what is the difference between a property and a set of methods that handles the getting/setting? Is it simply language? – JShell Jul 16 '15 at 14:55
  • methods and properties are different things when you write the code, but AFAIK, the getter and setter are compiled to methods to get and set the underling field. – Zohar Peled Jul 16 '15 at 14:57
  • I've added one last clarification to the question, if you wouldn't mind – JShell Jul 16 '15 at 15:19
6
//Method 1
public string name { get; set; }

//Method 2
public string name
public string getName() { return name;}
public string setName(string newName) { this.name = newName; }

The above 2 methods are not equivalent.

It would be more accurate to compare them like this:

//Method 1
public string name { get; set; }

//Method 2
private string name; // this is private, not public.
public string Name // this is a property, not a method.
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}

And if you want to play with access modifiers, like make the get public, and the set private, then you would do it like this:

public int maxTime { get; private set; }

More info on Auto-Implemented Properties and the compiler magic that goes on behind the scenes.

sstan
  • 35,425
  • 6
  • 48
  • 66
  • So, after a quick google search, I understand properties a bit. But what is the purpose? How are they different form a method that simply sets or gets a field? – JShell Jul 16 '15 at 14:53
  • Looks more cute than having a bunch of getX() and setX() methods – loli Jul 16 '15 at 14:57
  • So functionally, there is little difference, correct? – JShell Jul 16 '15 at 15:02
  • 1
    @Jesse: Correct. C#/.NET have been nice enough to include native support for the conceptual difference. But functionally, they are basically the same, and that's why, even without native support for properties, languages like Java are still able to support the concept of properties using methods. – sstan Jul 16 '15 at 15:08
3
public string name { get; set; }

What you have is Auto-Implemented property, which would internally have a backing private field (and compile time methods for get/set).

In C# code this would be equivalent to:

private string _name;
public string name
{
    get { return _name; }
    set { _name = value; }
}

At compile time, get/set are converted into method calls, somewhat similar to what you have.

For:

private int maxTime { public get; public set; }

The error is pretty clear, you can't have less restrictive access specifiers than the property itself. For example, if you want your public property to have a public get, but if you only want to allow setting the property from inside the class you can do:

public int maxTime { get; private set; }

You should also see: .Net Naming conventions, It would be better if you follow that, so you could have your property name starting with an upper case letter.

Habib
  • 219,104
  • 29
  • 407
  • 436
2

The first method is simply C# syntactic sugar for an automatically implemented property. It provides an implementation of the appropriate accessors when you come to compile it.

The second example is different. Here, you have a public-scope field (normally a no-no because of the principle of encapsulation) and two methods which access the variable. There's a subtle difference in semantic usage; typically properties are used to expose state, whereas a method normally indicates that the method has some computation behind it and isn't just going to return or change current state (again, this is a convention, not a hard-and-fast rule) Methods are normally styled with VerbAction naming (public Thing GetAThing() { }).

Auto-generated properties can have different access modifiers, but must only make the get or set less accessible than the overall modifier.

public int X { get; private set; } // OK
public int X { private get; set; } // OK
private int X { public get; public set; } // NOT OK
Matt
  • 1,648
  • 12
  • 22
  • 1
    When you say methods are normally styled with VerbAction naming, would getting something not be better suited for a property? – JShell Jul 16 '15 at 15:08
  • Yes, but there are occasions when methods are going to return something as well. I adopt the convention that a property getting is simply going to return some state without doing much in the process, whereas a method may return the results of something computationally heavy. I agree it's a grey area and open to convention. – Matt Jul 16 '15 at 15:22
1

When you use a property like in Method 1 (public string name { get; set; }), the compiler automatically generates a private backing string variable and public getter and setter methods.

The general idea is to make fields private and allow access only through public getter/setter methods. So if you use Method 2 declare the variable private.

I'd recommend to use ILDASM to peruse the generated IL, it helps to see what's going on under the hood.

The second error is simply what the compiler says. The visibility of the constructs must be consistent

Volkan Paksoy
  • 6,727
  • 5
  • 29
  • 40