Well I am learning properties and I am not sure about the following:
class X
{
private int y;
public X(int number)
{
this.Y=number; // assign to property
OR
this.y=number //?
}
public int Y;
{
get; set;
}
}
When you use auto-properties (get; set; or a variant thereof), the backing variable is not accessible. Those can, for the most part, be treated as simple variables, especially internally.
If you need to perform custom validation or mutation logic in the mutator, or otherwise have the need for an explicit backing variable, you cannot use auto-properties but have to write stub get and set methods yourself.
They do different things; I would do Y = number; and remove the (unused) field y. In an automatically implemented property, the compiler creates it's own field (with a horrible name that you can't see in C#) - you don't need to provide your own field. So:
class X
{
public X(int y)
{
Y = y;
}
public int Y { get; set; }
}
Other points: changed number to y to be clearer to the caller, and also you don't need this. since it isn't ambiguous (field vs parameter, etc).
Only assign to a field (private int y) inside the property representing that field (public int Y {get;set}). No where else in the class should the backing field be assigned to directly. Always do it through the property... yes even in the constructor. It follows from the do not repeat yourself (DRY) principle.
This is recommended because whenever in future you want to associate some behavior to be triggered by that assignment you only have a single place (the set accessor) to write code into.... not all the places where the field is assigned to !!
class X
{
private int y; //not strictly necessary but good for documentation
public X(int number)
{
Y = number;
}
public int Y { get; set; }
}
When you use autoproperties like:
public int Y;
{
get; set;
}
You don"t need a private property because it's autogenerated. so you class will be:
class X
{
public X(int number)
{
Y = number;
}
public int Y // no semicolon here, comment added for edit length
{
get; set;
}
}
Hope this helps
You have two choices :
class X
{
private int y;
public int Y
{
get { return y; }
set { y = value; }
}
public X(int number)
{
Y = number;
//equivalent to
y = number;
// but you should use the public property setter instead of the private field
}
}
or with auto-properties , it's even simpler :
class X
{
private int y;
public int Y
{
get; set;
}
public X(int number)
{
Y = number;
}
}
When not using auto-properties I always use the Property setter because there can or will be code in the setter that I need to be executed. This code could be a domain check or the raising of an event such as PropertyChanged.
A point I usually try to make about accessing backing variables:
Sometimes the public getter might contain complicated data validation,raising property changed events or some other complex code that is triggered when some external code changes it's value.
When changing that value internally (from inside the class), it might be a valid point to use the backing variable directly if your intention is to skip all the validation and events from the public setter. It's like saying "i'm the class instance, I know what I'm doing". This way the public setter is acting like a guard-dog, sanitizing external input, while I can still set the property internally to whatever I need.
class X
{
private int y; //not strictly necessary but good for documentation
public X(int number)
{
y = GetYValueFromDB(); //we assume the value from DB is already valid
}
public int Y {
get{ return y};
set {
if (ComplexValidation(value)
{
RaiseOnYPropertyChanged();
y = value;
}
}
}
Related
So after the availability of automatic implementation, and initialization of a property, do I even need a field for my property?
This seems much cleaner:
class A {
public int X {
get;set;
} = 1;
}
Than this:
class A {
int x = 1;
public int X {
get {
return x;
}
set {
x = value;
}
}
}
In the first case, the compiler is already providing a backing field - it's just implicit (and it's given a name that you can't refer to in code). Note that there has to be a backing field in the generated code, as a property itself is really just a pair of methods with some metadata linking them - the presence of a property does not add any state to the object. State is only stored in fields.
It's even cleaner when written on one line - I'd usually see this as:
class A
{
public int X { get; set; } = 1;
}
You dont need a backing field in this situation, but if you want to manipulate the Property with e.g a OnPropertyChanged() then you need to have a backing field
public int X {
get {
return x;
}
set {
x = value;
OnPropertyChanged()
}
}
Following OOP's best practices, is it better to have this code:
class Car {
private Driv driver;
public Driv Driver {
get { return driver; }
set { driver = value; }
}
}
Or this one?
class Car
{
public Driv Driver { get; set; }
}
While the second version is shorter, I feel like I'm breaking the main premise of the Encapsulation concept:
EVERY class should keep its privates to itself.
Hope the answer is not too trivial.
There really is no difference. If no private variable is created by the user then the code will be generated automatically for the private field. However, if the user wishes to do additional logic in the getter or setter of the property then declaring a private field is necessary.
Your first example is what's called a Property with a backing field
The second is called an Automatic property.
The purpose of a property with a backing field is so that you can control access to your private properties.
So... If for instance you want to, make a calculation before returning the value of your private field, you could do it in the one with the backing field.
Or lets say you have a car object with 10,000 miles on the clock... you would probably want to only increment its value using the Drive method, and hide the setter of the Property with the backing field
void Main()
{
var car = new Car();
car.Drive();
Console.WriteLine (car.Miles);
}
public class Car
{
private int miles;
public Car()
{
miles = 10000;
}
public int Miles
{
get
{
return this.miles;
}
}
public void Drive()
{
this.miles += 100;
}
}
You are not breaking encapsulation with the second approach. The second approach is syntactic sugar to make property definition less verbose. The benefit of this approach is that in the future if you need to modify the getter or the setter, you are setup to do so and will not break the API contract.
C#'s properties are simply syntactic representations of some underlying methods and variables. Essentially, the compiler turns:
public int Height { get; set; }
into:
private int height;
public int getHeight() {return height;}
public int setHeight(int h) {height = h;}
So, no you are not defying OOP encapsulation, but instead syntactically simplifying it. You could also do something like public int Height {get;} which is a nice way to create an immutable class member. It simply creates the property without a set method, so only the class itself can alter it.
Now, you only need to use properties with backing fields if you wish to do additional tasks when getting or setting a variable, such as raise an event, or update another variable. The compiler would turn:
private int height;
public int Height { get {return height;} set {height = value; OnHeightChanged();} }
into:
private int height;
public int getHeight() {return height;}
public int setHeight(int value) {height = value; OnHeightChanged();}
Hope this helps!
I noticed that in the Microsoft.Xna.Framework.Rectangle struct, there are plenty of properties that are just public int Bottom { get; } or public Point Center { get; }. I, for the life of me, can't figure out what's going on here. I've tried replicating this in some of my own structs, but I can't figure out how to give it a value in the first place without the set; keyword. What is it that the Rectangle struct is doing to {get;}?
The reason why the Rectangle.Bottom doesn't have a set is because it is a calculated value, Top + Height. If you would set that, what would you like to happen? Change the y position? Change the height? It is impossible to know. So you have to decide yourself and change the Top or Height based on what you actually want.
The idea of properties is not just to have a variable and set or get it. If it was we could just use public variables and that's it. Rather the idea is to allow validation and calculated properties.
public int Bottom
{
get { return Top + Height; }
}
As you can see, there is no need to set it to anything, since it will infer its value based on other values.
(Of course internally it will most likely not use the other properties, but rather the actual variables due to performance)
It means the underlying value that the property gives you access to cannot be set later on.. you can only "get" the underlying value.
When you instantiate a Rectangle, you have to pass it a few values:
public Rectangle (int x, int y, int width, int height)
My guess (without looking at the source code) is that the property values (Center, Bottom, etc) are all set in the constructor. You can't alter them later on.. either look for another property to set (i.e. X or Y), or create a new Rectangle based on the existing one.
var newRect = new Rectangle(oldRect.X, oldRect.Y, oldRect.Width, oldRect.Height);
For comparison, here's a portion of the source code from the System.Drawing.Rectangle struct, which is probably fairly close to what you're dealing with. Notice that you can set certain values via the constructor, which are then stored in private variables, and are accessible (but only changeable in some) properties.
public struct Rectangle
{
public static readonly Rectangle Empty = new Rectangle();
private int x;
private int y;
private int width;
private int height;
public Rectangle(int x, int y, int width, int height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public int X
{
get { return x; }
set { x = value; }
}
public int Left
{
get { return X; }
}
public int Y
{
get { return y; }
set { y = value; }
}
public int Top
{
get { return Y; }
}
...
...
}
Consider the following:
private int myVar;
public int MyProperty
{
get { return myVar; }
}
Here you see an example, taken directly from Visual Studio's C# snippets, showing how to implement a get-only property. You need to set the backing field, but it cannot be done via the property because this property is said to be a read-only property or a property with no setter method. The purpose of such properties is to make a contractual statement about your object "this property cannot be set."
This is similar to having a private setter, however, you cannot enforce access modifiers in an interface definition. Therefore, this syntax serves a specific purpose when defining data contracts and object interfaces, and that is to say "this property cannot be set, by contract, and no subclass may expose a public setter as part of this contract."
As an aside, you can circumvent access modifiers using reflection, but this is not the common case (and 99% of the .NET developers out there are probably unaware of this fact.)
Typically backing fields are set via a constructor, via reflection, or as part of object initialization.
This is also core syntax, it forms the basis of modern syntactic sugar. Consider the following property definition:
public int MyProperty { get; set; }
This is entirely syntactic sugar, and not actually valid for a C# 1.0 compiler. Today at compile time a backing field is generated on your behalf. Thus, the following syntax is only valid for interface definitions (as it would never return a meaningful value otherwise.)
public int MyProperty { get; }
The above is an (invalid) attempt to create a read-only property using the newer auto-property syntax.
References:
When should use Readonly and Get only properties
Using a backing variable for getters and setters
Is it possible to access backing fields behind auto-implemented properties?
https://msdn.microsoft.com/en-us/library/bb384054.aspx
https://msdn.microsoft.com/en-us/library/w86s7x04.aspx
I have class like bellow and I want to only let x be changed in Foo method and no other property. I can't use [Pure] like following example, because it locks all properties:
public class Test
{
private int x,y,z; //number of these properties is large
[Pure]
public void Foo()
{
//only x must be allowed to change
}
}
and I don't want to use something like this for all other properties than x:
Contract.Ensures(Contract.OldValue<int>(y) == y);
Contract.Ensures(Contract.OldValue<int>(z) == z);
...//and for other large number of properties
Is there any way to do this?
Unfortunately, standard way with Contracts I'm not found.
But you may use this way (this way have some constraints):
public class Test
{
public int x, y, z;//....
public void Foo()
{
x = FooBody();
}
[Pure]
private int FooBody()
{
int value = x;
//work with value as x
return value;
}
}
It seems there is no method implemented for this purpose in Contract class.
I understand how to create a getters and setters
public myClass
{
public int myVal { get; set; }
// more stuff
}
but I don't understand how to call it later on.
public myOtherClass
{
public myOtherClass()
{
myClass localMyClass = new myClass();
localMyClass.???set??? = 42;
// Intelisense doesn't seem to give any obvious options after I enter
// the period.
}
}
How should I set the value of myVal in localMyClass?
localMyClass.myVal = 42;
Getters and setters let you treat the values like public properties. The difference is, you can do whatever you want inside the functions that do the getting and setting.
Examples:
store other variables
private int _myVal, myOtherVal;
public int MyVal { get; set { _myVal = value; myOtherVal++; } }
make numbers up / return constants
public int MyVal { get { return 99; } set; }
throw away the setter
private int _myVal;
public int MyVal { get { return _myVal; } set { ; } }
In each of these cases, the user will feel like it's just a public data member, and simply type
localMyClass.myVal = 42;
int i = localMyClass.myVal;
The gettors and settors let you make an implementation of your own. Also, as Hogan says, "There are a number of libraries and add-ons [e.g. MVC.NET] that require you to use getter and setter functions" - even if it's for the trivial {get; set;} case.
Set:
localMyClass.myVal = 42
Get:
int variable = localMyClass.myVal;
From the outside, the syntax for accessing getters and setters is indistinguishable from that of accessing variables. Assignments translate into calls of setters, while plain expression uses translate into calls of getters.
In intellisense, the list of getters and setters should open upon placing a dot . after the variable name. Properties should have blue markers to the left of them (as opposed to magenta-colored markers to the left of methods).
You want this
localMyClass.myVal = 42;
to call the setter
and this
varName = localMyClass.myVal;
to call the getter.
Get: var tmp = localMyClass.myVal;
Set: localMyClass.myVal = 2;