What is the difference, if any, between
public int x;
and
public int x { get; set; }
?
The first one is called a field. The second one is a property, in this case an auto-implemented property.
Properties act like fields but use a getter and a setter function to retrive and set the value. Another way of writing the above property is as follows:
private int _x;
public int X
{
get
{
return _x;
}
set
{
_x = value;
}
}
The variable _x in this case is called a backing field. With an auto-implemented property you can't access the backing field or customize code in the getter/setter, but if you don't need to than it's shorter and more succinct.
As a rule in C# most of the time any public member should be exposed as a property instead of a field.
The difference between thise two is that a property can do something more than just get / set a variable.
take this example:
private int _x;
public int x
{
get
{
//do something
return _x;
}
set
{
if(_x != value)
PropertyChanged("x");
_X = value;
}
}
when we set the property - we notify something ( PropertyChanged()) that the value has changed. It would be very hard to do with just the field
The first one is public variable which can be accessed from anywhere.
The second one is public property
Check Properties tutorial for details.
Properties have many uses: they can validate data before allowing a
change; they can transparently expose data on a class where that data
is actually retrieved from some other source, such as a database; they
can take an action when data is changed, such as raising an event, or
changing the value of other fields.
Related
I am new to C# and am exploring the very basic of C# get and set properties. What I have found is, The get set accessor or modifier mostly used for storing and retrieving value from the private field.
In this case, What is the problem with using public fields?
Another thing, I have written some conditions inside get and set. The code is
public int Number
{
get
{
if(Number>10)return 10;
else
{
return Number;
}
}
set
{
if (value > 10)
{
Number = 10;
}
else
{
Number = value;
}
}
}
Whats the problem here?
And another interesting thing is, in VS, the recursive sign appears where I check the conditions.Can someone explain it, please?
I am new to C# and wants to learn from the basic.
Thanks in advance.
Initial Problem - StackOverflow
The problem is that you are inadvertently using recursion, which is going to lead to a stack overflow, because your getters and setters for the Number property are getting and setting the Number property, rather than a backing field.
It should at the very least be changed to this:
private int number;
public int Number
{
get
{
if(this.number>10)return 10;
else
{
return this.number;
}
}
set
{
if (value > 10)
{
this.number = 10;
}
else
{
this.number = value;
}
}
}
You are missing a private backing field. Your property is self-referencing (hence the recursion symbol).
Try this instead:
private int _number;
public int Number
{
get
{
if(_number > 10)
{
return 10;
}
else
{
return _number;
}
}
set
{
if (value > 10)
{
_number = 10;
}
else
{
_number = value;
}
}
}
As far as I can tell you are calling the Number several times inside your code.
And the recursive loop will run forever until it runs into a StackOverflow :)
I ran your code with :
this.Number = 100;
int num = this.Number;
Basically this should trigger the setter and the getter. When the if clause is setting the number to 10, the first recursion is entered since you are setting the number again. It will try to set the number to 10 recursively by Number=10
Add a backing field above number, like this:
private int number; // Backing field
public int Number
{
get { return number; } // Getter
set { number = value; } // Setter
}
The main idea of a property with public read/write access is to simply be a mutator and accessor for the internal state of their containing object.
When you have conditional logic inside these get/set methods their "contract" with consumers of the class is being broken....when I call the accessor/getter
var number = anInstance.Number;
...I expect to receive the current state of the anInstance object's number, not some logic-driven derivative of it. Similarly for the Mutator/setter
anInstance.Number = 123;
...I expect that to automatically set the internal state of the anInstance object's number.
If i set the Number in one statement...
anInstance.Number = 123; // I expect anInstance to have an internal state of 123 for it's Number
var x = anInstance.Number; // I expect 123 back, not 10
...if I then retrieve that value on the next line, I expect the same value back, but with your current implementation (if it wasn't also recursive - see below), when I set Number to 123, this is being ignored and the value of 10 is saved as the new internal state and when I then retrieve Number I would get back a value of 10.
It is not the concern of the Number property to be changing what the caller has requested be set as it's value. An invoker of the Number property rightly expects it's instructions to be followed and the invoker shouldn't have to know about weird internal getter-setter logic in order to function.
If you really need to get/set things in a conditional way, the place for the conditional logic is outside the class containing the Number property, i.e. replace the Number property with a simple auto-implement getter-setter and use in the following way.
int x = anInstance.Number > 10 ? 10 : anInstance.Number; // replaced getter logic outside the class containing the `Number` property
anInstance.Number = x > 10 ? 10 : x; // replaced setter logic
As for the reason why you are seeing the recursion symbol, that is because your code is recursively calling itself. The Number property is calling itself, instead of some backing field. Change the property to be like...
private int number;
public int Number
{
get
{
return number; // note the lower-case 'n' refers to the private field instead of the property
}
set
{
number = value;
}
}
Note, though, that there is no need to have a private backing field when you use your property in this simple way. If the intent is to have full read-write access, you could simply use a public field.
public int Number;
However, a property allows you to control access to fields, e.g.
public int Number { get; private set; }
which a simple public property does not allow, although you can use the readonly modifier to give this behaviour.
public readonly int Number;
However, another advantage of using a property over using a field is that it can offer greater control over how internal state is used/stored, e.g.this example is taken from MSDN
class TimePeriod
{
private double seconds;
public double Hours
{
get { return seconds / 3600; }
set { seconds = value * 3600; }
}
}
In this example, the caller of this class' Hours property is getting and setting a value of hours but under the hood the internal state of the class is storing/retrieving using seconds. This would not be possible with a public field.
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!
I am asking a beginner level question. Though I am working in MVC but I am really confused with a simple concept and that is "Properties". There are lot of questions that
I have already gone through but there is surely a doubt in mind and did'nt able to clear it up.
Actually c# properties used for getting and setting the value to the private fields.
Like
Public class MyClass
{
private int number;
public int Number{
get{ return this.number;}
set{ number=Value }
}
}
class Program
{
static void Main()
{
MyClass example = new MyClass();
example.Number = 5; // set { }
Console.WriteLine(example.Number); // get { }
}
}
Now , the value is assigned to property also and to the variable also. Right?
Now , here is my doubt::
When we create property in model for MVc structure, we only have
public int Number{get;set;}
If this is okay to work with then why we are creating unnecessorily one more field of private access specifier. If encapsulation is the reason for that or hiding the data then why not in model in MVC?
Actually, in the above class example can I only use
Console.WriteLine(example.number);
after declaring it public?
Then what's the use of creating property over here?
Properties can be used to a store and retrieve values from a backing field (number in your case) directly as in your first sample. But property getters and setters are ordinary blocks of code that you can use as you want. So you don't have to assign a backing field, but can derive the value of a property also from another property in a getter, e.g.
public int NumberTimesTwo
{
get
{
return Number * 2;
}
}
However, as a common scenario is to have a property retrieve and assign the value of a backing field, there is a shortcut that you can use:
public int Number { get; set; }
In this case, the compiler automatically creates a private backing field that the property retrieves in the getter and assigns in the setter, so the code is equivalent to the following, but less to type:
private int _number;
public into Number
{
get
{
return _number;
}
set
{
_number = value;
}
}
As the backing field is also private, you cannot access it from outside of the class directly.
private int myVar;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
You are implementing Encapsulation by using MyProperty, which is public to access myVar which is private and is accessible only in the block where defined, that is, your class and not outside it.
Btw, in what way does this QA not answer your question? Try going through this for further reference.
I have a class testClass
public class testClass
{
public int firstInt;
public int SecondInt { get; set; }
}
On an event in my page _Default, I am creating an object and trying to set the properties.
protected void Button1_Click(object sender, EventArgs e)
{
testClass objtestClass = new testClass();
objtestClass.firstInt = 1;
objtestClass.SecondInt = 2;
}
Value got set in both correctly. But firstInt and SecondInt behaves different. See the image.
Why both appears in different color?
Here
public class testClass
{
public int firstInt; // a class variable/Field
public int SecondInt { get; set; } // property
}
Variables/Field: A variable corresponds directly to a memory location. You define a variable with a single declaration statement. A variable can be a local variable, defined inside a procedure and available only within that procedure, or it can be a member variable, defined in a module, class, or structure but not inside any procedure. A member variable is also called a field
Properties: A property is a data element defined on a module, class, or structure. You define a property with a code block between the Property and End Property statements. The code block contains a Get procedure, a Set procedure, or both. These procedures are called property procedures or property accessors. In addition to retrieving or storing the property's value, they can also perform custom actions, such as updating an access counter.
See the Msdn link here http://msdn.microsoft.com/en-us/library/sk5e8eth.aspx for explanation
Also this question has a wonderful explanation here What is Difference between Property and Variable in C#
'firstInt' is a class field (variable) while 'SecondInt' is a .NET property. You can encapulate the processing SecondInt within your class if you need to by expanding the get and set methods.
The way SecondInt appears is the sign for properties. and the way you did it as:
public int SecondInt { get; set; }
makes it the property. properties are easy to use (no need to call setter/getter etc.). Now SecondInt behaves as a property of your testclass.
Edit:
By refactoring in visual studio, you can automatically (or manually) do this:
private string m_MyProperty;
public string MyProperty
{
get { return m_MyProperty; }
set { m_MyProperty = value; }
}
This way, your MyProperty property has been created, which sets and gets value for your private m_MyProperty string. and you can use it as:
String x = tstobj.MyProperty;
tstobj.MyProperty = x;
Actually when you write a property like this:
public int second {get; set;}
called auto property, C# automatically uses a private variable like
private int _second;
(much like your first variable)
and use your property as below
public int second{ get{ return _second;} set{ _second = value;} }
something like getSecond and setSecond methods in java.
so Properties are like two separate methods to getting and setting, and can has a backing field (a private variable) for storing data. Properties used for controlling access to internal data of class.
I just wonder is there is a logical reason why read-only and write-only automatic properties are not supported by c#.
(i.e. I mean properties with only a get or set, but not both. If you try to define an automatic property like this, you get a compiler error telling you that auto properties must have both get and set).
Is it just to stop people accidentally forgetting to add one?
Thanks
From the C# 3.0 spec:
When a property is specified as an
automatically implemented property, a
hidden backing field is automatically
available for the property, and the
accessors are implemented to read from
and write to that backing field.
Because the backing field is
inaccessible, it can be read and
written only through the property
accessors. This means that
automatically implemented read-only or
write-only properties do not make
sense, and are disallowed. It is
however possible to set the access
level of each accessor differently.
Thus, the effect of a read-only
property with a private backing field
can be mimicked like this:
public class ReadOnlyPoint {
public int X { get; private set; }
public int Y { get; private set; }
public ReadOnlyPoint(int x, int y) { X = x; Y = y; }
}
You can make a read-only property by making the setter private:
class A {
public int Foo { get; private set; }
}
What are you trying to get here when there never will be a set value?
MyPorperty { get; }
Even if you set the property, what is the benefit if you cannot get the value anyways?
MyProperty { set; }
If you want external code to only see set or get accessors, you can use the private keyword like this:
MyProperty { get; private set; }
or
MyProperty { private get; set; }
If you have only a getter, how could this auto-property return something usefull ?
The same logic apply for the setter.
:)
If your idea is inheritance then, you can flag it abstract and do what you want :
//this compiles successfully
public abstract Name { get; }
//this tooo
public abstract Age { set; }
Um, what would you do with such a property? There's no way to assign a value to an automatic property other than via the setter, and there's no way to read from one other than via the writer. So what use would it be to be able to read a value that can only ever be the default or to write a value that you'll never be able to get back?