简体   繁体   中英

{ get; set;} and access modifiers

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; }
}

Instead of the wrong private int maxTime { public get; public set; } private int maxTime { public get; public set; } 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.

//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.

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM