NOTE: This is not a question about auto-implemented properties. Auto-implemented properties are about properties without logic in the getters and setters while I stated in my code very clearly that there is some logic. This is not a duplicate of this question nither, since the question is really different, and so is the answer.
I see a lot of this:
private int _age;
public int Age
{
get
{
if(user.IsAuthorized)
{
return _age;
}
}
set
{
if(value >= 0 && value <= 120)
{
_age = value;
}
else
{
throw new ArgumentOutOfRangeException("Age","We do not accept immortals, nor unborn humans...");
}
}
}
But why do we need the backing field? Why no returning the Property itself?
public object Age
{
get
{
if(user.IsAuthorized)
{
return Age;
}
}
set
{
if(value >= 0 && value <= 120)
{
Age = value;
}
else
{
throw new ArgumentOutOfRangeException("Age","We do not accept immortals, nor unborn humans...");
}
}
}
Well, returning property itself leads to Stack Overflow exception:
public object Property
{
get
{
return Property;
}
set
{
Property = value;
}
}
Imagine
MyObject o = new MyObject();
// cause Stack Overflow exception
o.Property = null;
It easy to see why:
setting Property = null calls set
which call Property = value; which in turn calls set
which call Property = value;... and so on.
So if property stores some value the value should be stored in a field (you need a field), we can't use a property to store itself. If you want to shorten the code, put it like this (auto properties):
public object Property {
get; // let .Net create a backing field for you
set;
}
The property there is actually just two hidden methods: get_Property and set_Property. If you return Property from the getter of Property you are in fact causing an infinite recursive loop which will lead to a stack overflow exception: you are calling the method get_Property from the method get_Property, which in turn calls get_Property and so forth.
EDIT: As clarified in the comments, the property is only the two methods and nothing more. There is nothing to hold data; the backing field is what actually contains the data. If you want to store Age as data in the instance, something must hold that data which is why you need the backing field.
Auto-properties automatically create the backing field:
public object Property { get; set; }
In all other cases, the property is just two methods and all data storage is separate and you must handle it yourself.
Everytime you set a value to Property, the set-block will be called. So in your example it would be like:
Property = 10
-- Inside set: Property = Set
----- Called again set: Property = Set
----------- And so on and so o
n
But, you can do the following:
public int Property
{
get;
set;
}
public object Property
{
get
{
return Property;
}
set
{
Property = value;
}
}
This will return the property itself and end up in a recursive loop, a stack overflow. Therefore you want to return another object, for example _property.
Related
I have some doubts on the auto-implemented property. Why do we first get, and then set the value?
What you've have posted is not an auto property.
Below is an example class that contains 1 auto property and a custom property similar to what you have done.
public class MyPropertyClass
{
public MyPropertyClass(bool affectLogic)
{
_affectLogic = affectLogic;
}
private readonly bool _affectLogic;
public string MyAutoProperty { get; set; }
private string _myPropertyWithLogic;
public string MyPropertyWithLogic
{
get
{
if (_affectLogic)
_myPropertyWithLogic = "Some value";
return _myPropertyWithLogic;
}
set
{
if (_affectLogic)
{
_myPropertyWithLogic = "Some value";
}
else
{
_myPropertyWithLogic = value;
}
}
}
}
The autoproperty "MyAutoProperty" provides a mechanism for simply getting and setting property values.
What you have posted in a standard property that allows you to perhaps manipulate or return the property value based upon certain conditions. In your post you are checking to see if the value posted in is null before setting.
If you do not need to access the property outside of the class then you do not need to have the get method. If you remove the get then you are creating a "WriteOnly" property which is bad practice.
Create a public method on the class that accepts the "Alert" value. If you dont need to access the property outside of the class then dont create a property at all.
public void SetMyProperty(string value)
{
_myPropertyWithLogic = value;
}
I'm making a new class and I caught myself wondering:
Is there any difference between writing:
public string temp;
And writing:
private string temp;
public string temp_
{
get { return temp; }
set { temp = value; }
}
I'm guessing this is kind of a newbie question, but I didn't find an absolute answer...
In both cases it seems I can access the object outside the class.
Is the private form just a sloppy way?
Yes, the difference is that you have a property. Properties in C# are a syntax sugar over having a pair of get and set method. The compiler in fact takes the code blocks and creates two separate methods: get_PropertyName and set_PropertyName, where PropertyName is the name of your property. These methods have the exact logic you implement in the get and set blocks respectively, and the code using your property will in fact be calling these methods behind the scenes.
The advantage of this is that you have full control over the way the value is set and retrieved.
Example - imagine you want to store age:
public int Age;
Now anyone using your class can easily set the age to any value they please - 1000, -1, anything.
Now if you have a property, you can make sure that doesn't happen:
private int _age = 0;
public int Age
{
get { return _age; }
set { if ( value >= 0 && value < 120 ) _age = value; }
}
Most of the time it is beneficial to declare public fields as public properties even though you don't need any validation logic, because you might need to add one in the future and if you act proactively by creating a property in the first place, other code using your library won't need to be recompiled to work.
Properties also give you more fine-grained control over the visibility of getters and setters. You can have a public property with public getter and private setter to make sure only the class itself can change the state of the property.
public Connected { get; private set; }
In addition, there are places where you really need to have a property. One of those is using the INotifyPropertyChanged interface in the MVVM pattern for WPF, UWP and others. Data binding requires a property to be bound to (although this is not completely true if you don't need notifications, as the new {x:Bind} syntax in UWP can bind to ordinary fields).
If you use this one
public string Age;
you can set the variable to any value Age = "99999999" .
if you use this
private string Age;
public string Age_
{
get { return temp; }
set { if ( value >= 0 && value < 120 ) temp = value;
else // write some message
}
}
you can write some code inside . and make some tests Before you set or get the value of the variable
Never Declare a property's first character with lower case . The property name should be like:
private string temp;
public string Temp
{
get { return temp; }
set { temp = value; }
}
Property follow the encapsulation rules. Property is a encapsulated field of variable. we can't restrict value get and set for variable at a time but by property you can. You can also define business logic or programming construct inside property. Property is transparent with any kinds of templating or persistent context(EF).
This question already has answers here:
How to avoid stack overflow errors when defining set accessor in C#
(4 answers)
Closed 6 years ago.
I have an object with a property for which I want to create a custom setter and also keep the automatic getter:
public class SomeObject
{
public int SomeProp { get; set; }
public Nullable<short> MyProp
{
get
{
return MyProp;
}
set
{
if (value != null)
{
SomeProp = SomeWork(value);
MyProp = value;
}
}
}
}
The problem is that I get a Stackoverflow error on the getter. How do I implement a property where I keep the getter as it is but only modify the setter?
You need to use a backing field for your property. You're getting a SO error because you're recursively referencing your MyProp property in its own getter resulting in infinite recursion.
private short? _myProp;
public short? MyProp
{
get
{
return _myProp;
}
set
{
if (value != null)
{
SomeProp = SomeWork(value);
_myProp = value;
}
}
}
NO, it's not possible. Either you make it a complete auto property (OR) define both the getter and setter in which case you will have to provide the backing field since compiler won't create one for you.
You get the exception because you're essentially doing infinite recursion in your property.
Unfortunately what you're describing isn't possible in C# yet, you need to define the backing field yourself.
You cannot do that. You either use custom getter setters (both, not single) or you stick to auto getters.
In your code getter of your property is trying to access getter of itself (which is going to access the same getter and so on and so on)
So it's an endless loop which is going to destroy all the world and bring the end of humanity
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.
Do I need to declare a class-level variable to hold a property, or can I just refer to self.{propertyname} in the getter/setter?
In other words, can I do this? (where I haven't defined mongoFormId anywhere):
public string mongoFormId
{
get
{
return this.mongoFormId;
}
set
{
this.mongoFormId = value;
revalidateTransformation();
}
}
You can either use automatic accessors or implement your own. If you use automatic accessors, the C# compiler will generate a backing field for you, but if you implement your own you must manually provide a backing field (or handle the value some other way).
private string _mongoFormId;
public string mongoFormId
{
get { return this._mongoFormId; }
set
{
this._mongoFormId = value;
revalidateTransformation();
}
}
UPDATE: Since this question was asked, C# 6.0 has been released. However, even with the new syntax options, there is still no way to provide a custom setter body without the need to explicitly declare a backing field.
You need to set a field variable and store the value there, if you're going to use custom getter and setter.
With the code you have right now you will be running into a stack overflow exception. When you assign something to mongoFormId, you'll execute the line this.MongoFormId = value;. This is an assignment to mongoFormId, resulting in executing the line this.MongoFormId = value;, and so on. It won't ever stop.
The correct way is a field:
private string _mongoFormId;
public string mongoFormId {
get { return this._mongoFormId; }
set {
this._mongoFormId = value;
revalidateTransformation();
}
}
You should have a backing variable. Take a closer look:
get { return this.mongoFormId; }
Is going to call the getter on mongoFormId, which will call that code again, and again, and again! Defining a backing variable will avoid the infinite recursive call.
Check MSDN Properties Overview
While a property definition generally includes a private data member,
this is not required. The get accessor could return a value without
accessing a private data member. One example is a property whose get
method returns the system time. Properties enable data hiding, the
accessor methods hide the implementation of the property.
You can do it both the ways.
If you want to have a class level member variable then do it this way -
public class sampleClass
{
private string _mongoFormId;
public string mongoFormId {
get { return _mongoFormId; }
set {
_mongoFormId = value;
revalidateTransformation();
}
}
}
Or do this simple in class, if no need for revalidateTransformation() execution call there
public class sampleClass
{
public string mongoFormId {get; set;}
}
This won't work since you get a recursive call to the property.
If I'm not mistaken, the result will be a StackOverflowException.
You must use a variable.
private string mongoFormId;
public string MongoFormId
{
get
{
return this.mongoFormId;
}
set
{
this.mongoFormId = value;
revalidateTransformation();
}
}
If you don't have to execute revalidateTransformation, you can use the auto-property.
This will create a backingfiled for you behind the scene.
public string MongoFormId { get; set; }
With the code you wrote, you are creating a recursive endless loop on both the get and set. The this keyword refer to the current class, not the property you are in.
So yes, you need to declare a private field. And to avoid confusion, create properties following the MSDN Naming Guideline (Use Pascal case for properties, camel case for private fields). And please do the same for your methods, it should be RevalidateTransformation instead of revalidateTransformation if you follow the C# convention instead of java's.
private string mongoFormId;
public string MongoFormId
{
get
{
return mongoFormId;
}
set
{
mongoFormId = value;
RevalidateTransformation();
}
}
public string mongoFormId {
get {
return this.mongoFormId;
}
set {
this.mongoFormId = value;
revalidateTransformation();
}
}
this way you have the Function recursive on all paths
The only way i see is to use a private data member. As other boys tells.