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; },
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
Related
Below, when I attempt to use the _currentTemp variable, that was supposed to be auto-generated via the auto properties functionality, I get a variable not found message:
The name _currentTemp does not exist in the current context.
Using { get; set; } should automatically create this private variable (_currentTemp), right?
public class DogTemperature
{
public double CurrentTemp { get; set; }
public DogTemperature(double dCurrentTemp)
{
_currentTemp = dCurrentTemp; //***this line***
}
}
Backing fields created by auto-properties are not available for you to interact with in your source code, as it is generated by the compiler.
If you want to interact with the backing field, you'll need to create your properties the verbose way.
In my opinion defining a property like this is complely pointless if all you want to do is store a value.
double _currentTemp;
public double CurrentTemp
{
get { return _currentTemp; }
set { _currentTemp = value; }
}
All you're doing here is giving the private context two ways to set the same value. You can set the _currentTemp field directly or you can set the CurrentTemp property which sets the _currentTemp field. If you are not doing anything with the property then just use the default get/set like this:
public double CurrentTemp { get; set; }
If you need to do more complex work in the property then go ahead and define a field like this. More complex work such as conditions, calculations or raising events:
double _currentTempFarenheit;
double _currentTempCelcius;
public double CurrentTemp
{
get
{
if(UseFarenheit)
return _currentTempFarenheit;
else
return _currentTempCelcius;
}
set
{
if(UseFarenheit)
_currentTempFarenheit = value;
else
currentTempCelcius = value;
}
}
Furthermore if you only want the value of your property to be set by the constructor of your DogTemperature class then you should make the setter private. This will only allow the property to be publically read.
public double CurrentTemp { get; private set; }
Based on #Alex Gravely's answer...
If I'm understanding your necessity for a full property: you can create full properties and backing fields like this:
private double _currentTemp;
public double CurrentTemp
{
get { return _currentTemp; }
set { _currentTemp = value; }
}
Then in your constructor for DogTemperature, you just need to set the CurrentTemp to the double you passed in:
public void DogTemperature(double temp)
{
DogTemperature = temp;
}
Depending on what usage you want to get out of the CurrentTemp property - i.e. to display in a View and updating it; you may want to read into implementing INotifyPropertyChanged. Here's a link: https://msdn.microsoft.com/en-us/library/ms229614(v=vs.100).aspx
If it is just a plain old property, and not used for anything special (such as in a model, for example); then the
public double DogTemperature { get; set; }
property will suffice; setting it in the constructor as above.
Hope this helps!
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?
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;
...
}
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.
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.
Values of these properties could be defined inside constructor only:
// C#, all versions
private readonly int _foo;
public int Foo
{
get { return _foo; }
}
// C#, version 6+
// actually, this is the same as above, but backing field is generated
// for you by compiler
public int Foo { get; }
Note, that if you know the name of backing field, you can change its value through reflection, thus, this will change result of property getter, but this code will fail, because there is no setter:
typeof(SomeType).GetProperty("Foo").SetValue(bar, 1)
Value of this property could be defined inside any method of declaring type, but also one can easily change it using reflection, without knowledge about backing field, because there is setter:
// this will work fine: typeof(SomeType).GetProperty("Foo").SetValue(bar, 1)
public int Foo { get; private set; }
In other words: the main difference, that first one has get-method only, while the second one has both get- and set- methods.
Case 1: With no setter, an auto-implemented property can only be set while declaring the property or inside the constructor as a backing property is created. Therefore, acting as a read-only field.
Case 2: With no setter, a property that is not auto-implemented, can only be set while declaring the property as no backing field is created.
Case 3: With a private setter, a property can be set anywhere inside the class.
Usually I would build my field like this:
private string name;
public void setName(string name){
this.name = name;
}
public string getName(){
return name
}
that works perfectly when doing this: string myString = object.getName() or object.setName("Alex").
However, I thought I might give the inbuilt C# functions a try.
So I did this:
private string name { get; set; }
however, that won't work at all. When I try to access the field with object.name, I can't even access it due to private restriction.
Did I misunderstand something about these predefined get/sets?
If I had to mark every field as public, why should I even use getters or setters? I could access the field like in the snippet above without get and set?
You're mixing up way too many things - you might want to read a book on C#, really. It usually takes some time to get rid of some of the preconceptions from your old programming language - but you really do want to do that; even Java and C# are incredibly different when you go beyond the surface appearance.
First, nothing is forcing you to use auto-properties. If you want to use properties while keeping your manual backing fields, you can simply use this:
private string name;
public string Name { get { return name; } set { name = value; } }
If you do want to use auto-properties, you have to understand that the backing field is hidden - you're only declaring the property; and you want that property to be public (though you can also use accessibility modifiers on the individual get/set "methods", e.g. private set). But the field is never accessible - it's "always" behind the property.
To mirror your original code, this is what you want:
public string Name { get; set; }
Only if you ever need to move away from using auto-properties (that is, you need to add some logic to either the getter or the setter), you will have to reintroduce the manual backing field, and stop using auto-properties - see the first code sample in my answer.
Did I misunderstand something about these predefined get/sets?
Yes, you did. The property itself has to be public. If you're using auto-properties, then you can't do any validation since the backing field is compiler generated. If you want to actually do something with the value before, you can use a property with a backing field:
private string name;
public string Name
{
get { return name; }
set
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("name cannot be null");
name = value
}
}
Because this:
public string Name { get; set; }
Generated a backing field like this:
[DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated]
private string <Name>k__BackingField;
public string Name
{
[CompilerGenerated]
get
{
return this.<Name>k__BackingField;
}
[CompilerGenerated]
set
{
this.<Name>k__BackingField = value;
}
}
Just do
public string Name { get; set; }
That compiles down to a private field with an unspeakable name, and a public property. That public property has a public get method and a public set method.
Seems to be exactly what you want.
Alternatively, use
public string Name { get; private set; }
Your get method will be public as before, but the set method will be private then.
As of C# 6 (Visual Studio 2015), you can even do
public string Name { get; }
In that case, there is no set method, not even a private one, but you can assign to the underlying field through the property in the constructor.
Did I misunderstand something about these predefined get/sets?
Yes, a bit.
If I had to mark every field as public, why should I even use getters or setters? I could access the field like in the snippet above without get and set?
This is the part that you're missing. The syntax you are talking about it called an auto-implemented property. That is, when you write:
public string Name { get; set; }
the C# compiler generates a private field, getter, and setter behind the scenes for you. You can see them if you look at the metadata for your class, and get access to them via reflection. They have the exact same names as the getter or setter you would write yourself (typically get_Name and set_Name). The only difference is, you didn't have to write them.
The reason to do this is because most getter/setter pairs only exist to add a layer of abstraction over a private field, and consist of a single return name or name = value line of code. If that's all you want, you may as well let the compiler write it for you.
However, if you ever needed something more complex, you can manually implement the getter and setter yourself, and callers won't know the difference. In other words, if you change:
public string Name { get; set; }
to
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
RecalculateSomeStuff();
}
}
then the metadata for your class is identical. Anyone using your class does not have to even be recompiled to pick up the new setter, because as far as the callers are concerned, they're still called set_Name directly.
What the others want to tell you is that you should deferentiate between fields (privates) and properties (public) (is not a rule but a convention)
private string name;
public string Name{ get; set;}
// you can acces to the property:
var objectName = YourObject.Name
// and set the value of your property:
YourObject.Name = "whatever"
First of all the equivalent of your code is
private string _name;
public string Name
{
get {return _name;}
set { _name = value; }
}
OR simply
public string Name { get; set; }
To define the accessibility level of the "Name" field, you put the access modifiers (public, protected, etc.) before get or set
Example
//Read only properties
public string Name
{
get {return _name;}
private set { _name = value; }
}
To have more details and see difference between public fieal and public property see Difference between Auto - Implemented Properties and normal public member
PS :
To write this in Visual studio you can use snippet, type prop keyword then tab key or propfull and press tab key. press tab key our shift+tab to navigate between highlighted fields
For an object sellprint declared as static in the class
private static string sellprint = "";
public string Sellprint
{
get { return sellprint; }
}
public void SetSellprint(string x)
{
sellprint = x;
}
How is this
different from
public string Sellprint
{
get; set;
}
internally.
I could not find any examples of code 1 on msdn. what does it translate into?
The compiler creates a getter method for your property in the first code that returns the value of sellprint field because you implement only the getter method.In the second code, both getter and setter methods creating by compiler and also the backing-field.That's the difference.
You can verify that using ILDASM.exe:
First, consider this code:
class Foo
{
private string _value;
public string Value
{
get { return _value; }
}
public void SetValue(string str)
{
_value = str;
}
}
As you can see there is only one method generated by compiler which is get_Value.
If we change it like this and make the Value an auto-implemented property:
class Foo
{
public string Value { get; set; }
}
You can see that compiler creates both getter (get_Value) and setter (set_Value) method and also create a private backing field for the property.
There is no pros or cons about the functionality except in the second code you are doing the same work with less code.
1) should not work because there is no sellprint - assuming you have a field named sellprint and just forgot in your code snippet, you provide a get accessors and a method instead of the set accessors, which is kinda strange.
2) will create the field required automatically (and will not tell you the name, so you cannot accidentally use it)
There is not difference between those two though.
In C# do properties need to reference private member variables, or can I just declare the properties and use them directly in the class code?
If the former is the best practice, then does that rule out using C# property short-hand? I.e.
public string FirstName { get; set; }
Properties, when implemented like this:
public string FirstName { get; set; }
Automatically create a private member variable (the compiler does this for you), so you don't have to worry about it. This will behave exactly the same as if you do:
private string firstName;
public string FirstName {
get { return firstName; }
set { firstName = value; }
}
There is no reason not to use the automatic properties ( { get; set; } ). The provide the same advantages as making your own private member variable.
In addition, if you later decide you need to do extra processing (for example, if you decide to implement INotifyPropertyChanged in your property setter), you can add this without changing your public API, but putting a backing field in manually.
You don't need properties to access private fields but in general it is considered best practice.
And you can use auto-properties (short hand) untill you need to add more functionality to a property, like validation. Changing it to a 'real' property is always a non-breaking change.
Properties created like this
public String Caption{ get; set; }
this will be compiled as
[CompilerGenerated]
private string <Caption>k__BackingField;
public string Caption
{
[CompilerGenerated]
get
{
return this.<Caption>k__BackingField;
}
[CompilerGenerated]
set
{
this.<Caption>k__BackingField = value;
}
}
The above code is extracted after compilation using reflector tool.
They do not need to reference private member variables. You can use them directly in the class.
Properties do not need to reference private member variables. It is best practice, though, to have them do so. You can think of properties as methods if it makes it easier to understand. You can run code inside of them. You can return whatever you want. You can call methods and use private member variables. You can even simply return a constant.
I use private member variables in almost all cases. It allows me to create a readonly property, or to provide some rules to those outside my class of getting or setting properties that my class doesn't have to follow.
To add on to Reed's answer, inside of your code (within the class itself) the member functions should adhere to this and actually use the Property rather then the actual private member. For instance if you had this:
public string FirstName { get; set; }
And you had a strange method called public char GetFirstLetter() that returned the first letter in a person's first name you'd want to do it like this:
public char GetFirstLetter()
{
return FirstName[0];
}
Instead of actually using your private variable. When you set a property a programmer may have written code to set it in a particular manner. So it only makes sense to simply use that property within your class methods.
C# can reference private variables as in:
public class A
{
private string _b;
public string B
{
get { return _b; }
set { _b = value; }
}
}
The get;set; designation is automatic properties which when compiled will generate the private variable for you, as a way to make it easy to setup your code.
Using properties is the best way to provide a method of control and security to the attributes in a class, always keep the attributes private if possible.
if you use like
public string FirstName { get; set; }
compiler will automatically adds getters and setters for this property automatically.it not a bad practice.
Here is the proof
if you declare
private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
like this also compiler will takes it as
so its not ruled out... :)