Been trying to figure out why I am unable to initialize new objects with property values. Probably overlooking something very basic - but can't grasp what it is. Hopefully I can phrase my question in such a way that it will be useful for others as well.
In my Main class I have the following code which calls a custom usercontrol that I have defined in another class.
BallUc ball = new BallUc {
Number = 100
};
MessageBox.Show(ball.Number.ToString()); //this works and returns '100'.
Relevant part of my BallUc code;
private int _number { get; set; }
public int Number{
get { return _number ; }
set { _number = value; }
}
public BallUc() {
InitializeComponent();
MessageBox.Show(this.Number.ToString()); //this doesn't work and returns '0'.
}
I need the number variable to compute some functions in the BallUc class. Hope that my question is clear, if anything needs clarification please let me know. Thank you in advance for your time!
Property assignment by object initializers is done after the constructor has executed. If you need the value to be available in the constructor, you have to pass it as argument:
public BallUc(int number)
{
InitializeComponent();
Number = number;
MessageBox.Show(Number.ToString());
}
Then instantiate your control like this:
var ball = new BallUc(100);
The constructor is executed before you set the value on the property
You can pass this parameter through constructor properties:
private int _number { get; set; }
public int Number{
get { return _number ; }
set { _number = value; }
}
public BallUc(int number) {
Number = number;
InitializeComponent();
MessageBox.Show(this.Number.ToString());
}
Related
Read only properties can be assigned in a constructor. But when I try to explicitly implement get method, compiler shows an error (Property cannot be assigned to -- it is read only.) Can I implement getter or it's supposed to be without implementation?
public class PersonalIncome
{
private decimal _anualRate;
public decimal AnualRate
{
get { return _anualRate != 0 ? _anualRate : 40_000; }
}
public PersonalIncome(decimal paymentRate)
{
switch (paymentRate)
{
case var rate when (rate > 300):
AnualRate = rate; // **Property can not be assigned to -- it is read only.**
break;
default:
break;
}
}
}
You can implement the getter, but then you can only assign values to the backing field directly:
_anualRate = rate;
Once you decide against using the convenience of the auto-property, you have to do everything by yourself.
Your class could be rewritten like this:
public class PersonalIncome
{
public decimal AnualRate { get; private set; }
public PersonalIncome(decimal paymentRate)
{
AnualRate = paymentRate > 300 ? paymentRate : 40_000;
}
}
You refer to a property with a readonly backing-field.
That´s exactly what the compiler also generates from C#6 upwards when using an auto-implemented property with a default-value:
int MyProperty { get; } = -1;
This will be translated to the following:
readonly int _myProperty = -1;
int MyProperty { get { return this._myProperty; } }
Now the compiler replaces every call to your property by the backing-field. However this only works for auto-properties that do not have a body defined. In your case you already have one, which is why the compiler can´t replace that one. As a property itself is nothing but a get- and a set-method, what you want to do is the following, which is obvious non-sense:
int get_MyProperty() { return this._MyProperty; }
...
this.get_MyProperty() = 1;
The reason this works for an auto-property is that the compiler knows how to replace the call to the property. However suppose your own getter was more complex:
get
{
DoSomething();
return this._myProperty + 5;
}
Now the compiler can´t replace the call to the property.
So the only way to have your own get-implementation tigether with a property which is get-only, is to use the backing-field:
this._myProperty = 1;
I am a bit confused with the get set property in C#.
I have the simple code below:
using System;
class Example
{
int _number;
public int Number
{
get
{
return this._number;
}
set
{
this._number = value;
}
}
}
class Program
{
static void Main()
{
Example example = new Example();
example.Number = 5; // set { }
Console.WriteLine(example.Number); // get { }
}
}
The code above using get set properties. However, if I delete the get set code like below code, the results stay the same.
using System;
class Example
{
int _number;
public int Number;
{
}
}
class Program
{
static void Main()
{
Example example = new Example();
example.Number = 5; // set { }
Console.WriteLine(example.Number); // get { }
}
}
My query is, what is the get set code used for? In the above program, the results are same. Can you give me some simple code which show the get set usage?
In your code, Number is simply a public field, as evidenced by the semicolon (;) at the end.
public int Number;
It is not a property, you just have an empty set of brackets right underneath which led to your confusion. If you were to remove the ; then you would actually have a property that is missing it's get, and would not compile at all.
All properties need to have a getter (setters are optional). If you want to avoid writing them, you can use auto properties, which take care of the backing field without you having to get involved:
public int Number { get; set; } // No field required
Note: A common usage pattern you'll see involving auto properties is the following:
public int Number { get; private set; }
This allows for properties that can be read from anywhere, but can only be modified from within the class they belong to.
EDIT: To answer your question, the main difference between fields and properties is in encapsulation. You can read more about the general differences between fields and properties here.
However, the example you have given has one additional difference, the private set. A normal field can be written from and to throughout the program. A property with a private setter however can only be modified from inside the class it belongs to.
Example:
public class Foo
{
public int Id { get; private set; }
public string Name;
public Foo()
{
this.Id = 1; // This works!
}
}
Here, Name is a field and Id is a property with a private setter. Notice that we modify Id in the constructor and that works, because it is within the class Id belongs to. Moving outside the class however:
var foo = new Foo();
// Field (no get and set):
foo.Name = "test" // Works
string bar = foo.Name; // Works
// Property (get and *private* set)
int i = foo.Id; // Works, because get is public
foo.Id = 2; // Doesn't work, because set is private
Lets have a simple class with an int property
public class SimpleClass {
public int myInt { get; set; }// for having a property and not "public int myInt;", see Jon Skeet remark
}
I instanciate it twice assigning myInt or not
assignedObject = new SimpleClass() { myInt=0};
notAssignedObject = new SimpleClass();
Now by reflection, I query the value of myInt in each case using
Object value;
value=assignedObject.GetType().GetProperties().Where(o=>o.Name.Equals("myInt")).First().GetValue(assignedObject,null)
value=notAssignedObject.GetType().GetProperties().Where(o=>o.Name.Equals("myInt")).First().GetValue(notAssignedObject,null)
I am getting twice 0 for myInt, but I need to be able to differenciate them. How?
Unless you have code to specifically remember the difference between a property which has been initialized with its default value, and one which hasn't been set at all, you can't tell the difference. I have two suggestions, however:
You could make it an int? property, and then check whether the value is null. Of course, it's possible for it to be set to null explicitly, unless you prohibit that, but it may be good enough.
You could keep a separate bool value to know whether or not it's been set explicitly, and just set it in your property setter, along with the value.
Sample code for the second option:
public class SimpleClass
{
private int value;
private bool valueSet;
public int Value
{
get { return value; }
set
{
this.value = value;
this.valueSet = true;
}
}
public bool ValueSet { get { return valueSet; } }
}
I am learning C#, and am learning about making fields private to the class, and using Getters and Setters to expose Methods instead of field values.
Are the get; set; in Method 1 and Method 2 equivalent? e.g. is one a shorthand of the other?
class Student
{
// Instance fields
private string name;
private int mark;
// Method 1
public string Name { get; set; }
// Method 2
public int Mark
{
get { return mark; }
set { mark = value; }
}
}
Finally, would Method 2 be used when you want to for example perform a calculation before getting or setting a value? e.g. converting value to a percentage or perform validation? e.g.
class Student
{
// Instance fields
private string name;
private double mark;
private int maxMark = 50;
// Method 1
public string Name { get; set; }
// Method 2
public double Mark
{
get { return mark; }
set { if ( mark <= maxMark ) mark = value / maxMark * 100; }
}
}
Yes, the Method2 is the way to go when you have a custom getter and setter function. By default when you use Method1, there will be a default private property handled internally. Please refer this URL for more details.
Sample:
string _name;
public string Name
{
get => _name;
set => _name = value;
}
Yes, Method 1 is a shortcut to Method 2. I suggest using Method 1 by default. When you need more functionality, use Method 2. You can also specify different access modifiers for get and set.
Here is an interesting tidbit where I could not really find on the interwebs. The idea is that if you have a property such as int a { get; set; } it could set itself.
How do you make the property set itself with int a { get { } set { } }?
What is happening inside of set;?
Here is what I tried to do:
public string Symbol { get { return Symbol; } set { Symbol = value; NotifyPropertyChangedEvent("Symbol"); } }
But it obviously creates a Stack Overflow because it is essentially calling itself over and over.
And I don't want to create 10-20 private variables to work along side of my properties, I want to know what is happening in set;.
Thank you.
set; just creates a private variable that you can't see. You'll need those 10-20 private variables, sorry.
You have to create private variables.
Unfortunately, that's the only way in the specific circumstance you have here.
If you need custom logic, you'll need to provide the backing field yourself:
private string symbol;
public string Symbol
{
get { return symbol; }
set { symbol = value; NotifyPropertyChangedEvent("Symbol"); }
}
And I don't want to create 10-20 private variables to work along side of my properties, I want to know what is happening in set;.
With an automaticaly property (ie: public string Symbol { get; set; }), the compiler creates the backing field automatically. However, there is no way to introduce logic (ie: raise your event) without managing the backing field(s) yourself.
It generates a backing field for you when it gets compiled. You cannot access it via intellisense because it has not been created yet. It is equivalent to the following where '_a' has not been generated yet.
private int _a;
public int a
{
get { return _a; }
set { _a = value; }
}
You could, however, simply set the property itself from inside of your class.
public int a { get; set; }
a = ...;
Additionally, you can set modifiers on the get and set if you only want to be able to set it internally;
public int a { get; private set; }