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
Related
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'm new to C#, and I'm working with a class that has a Rectangle field. I've read that Properties are the most accepted way to declare public fields, so I tried something like this:
public class MyClass
{
public Rectangle MyBox { get; set; }
public UpdateBox(int x, int y)
{
MyBox.X = x;
MyBox.Y = y;
}
}
It won't let me do MyBox.X = x because (from what I've read), Rectangle is a struct, and the getter returns a copy of the Rectangle, so I would not be modifying the value I want.
What is the standard for updating fields like this? I've found two solutions so far:
Creating a new Rectangle to store in the variable:
public class MyClass
{
public Rectangle MyBox { get; set; }
public UpdateBox(int x, int y)
{
MyBox = new Rectangle(x, y, MyBox.Width, MyBox.Height);
}
}
but this seems like it would not be very memory efficient. Then there is just not making Rectangle a property:
public class MyClass
{
public Rectangle MyBox;
public UpdateBox(int x, int y)
{
MyBox.X = x;
MyBox.Y = y;
}
}
What is the standard for this kind of functionality?
By convention you can use a struct as a field and access its internal fields directly, if you want to use it as a property, then make a proper setter for it.
I, personally only use struct types as fields other than properties, maybe a read only property for public access (for encapsulation purposes), grants me safety and general organization of my code.
Your 3rd block of example code is the most correct form in my view, and no its not memory inefficient, Rectangle MyBox is already allocated in memory and already consuming its most by the time the constructor is called.
Also, let us keep in mind here, a property is a "shortcut" function to access some data, but if this data ought to be stored somewhere and wont likely change (default get/set accessors), then it's not any different from a normal field.
This is my favorite way of dealing with this:
public class MyClass
{
private Rectangle _MyBox; // or protected idk.
// This is public and read only.
public Rectangle MyBox { get { return _MyBox; } }
public UpdateBox(int x, int y)
{
_MyBox.X = x;
_MyBox.Y = y;
}
}
The clearest approach for non-speed-critical applications is to use the pattern:
var temp=myThing.TheProperty;
temp.X = whatever;
temp.Y = whatever;
myThing.TheProperty = temp;
If the structure behaves as a bunch of independent variables fastened together with duct tape, the above approach will avoid having to either have the client code know about all of its fields, or have the struct include lots of boilerplate WithX, WithY, etc. factory methods.
If speed is important, then one should either have structures exposed in fields or arrays [as opposed to other collection types], or--if one wants to retain encapsulation--include accessor methods:
delegate void ActionRR<T1,T2>(ref T1 p1, ref T2 p2);
void ActOnBounds<TExtra>(ref Rectangle bounds, ActionRR<Rectangle, TExtra>proc, ref TExtra extra)
{
proc(ref _bounds, ref extra);
}
Note that generating delegates to call ActOnBounds will make it slow, but it may be used efficiently by passing a static delegate and a ref valuetype. Unfortunately, while C# includes lots of nice syntactic sugar for closures, it does not provide such help with constructs like the above.
I read this answer: https://stackoverflow.com/a/9928643/16241
But I obviously don't understand it because I can't figure out why my method is impure. (The method in question is ToExactLocation()).
public struct ScreenLocation
{
public ScreenLocation(int x, int y):this()
{
X = x;
Y = y;
}
public int X { get; set; }
public int Y { get; set; }
public ExactLocation ToExactLocation()
{
return new ExactLocation {X = this.X, Y = this.Y};
}
// Other stuff
}
Incase you need it here is the exact location struct:
public struct ExactLocation
{
public double X { get; set; }
public double Y { get; set; }
// Various Operator Overloads, but no constructor
}
And this is how I call it:
someScreenLocation = MethodThatGivesAScreenLocation();
if (DestinationLocation == someScreenLocation.ToExactLocation())
{
// Do stuff
}
When I do that, ReSharper flags it with "Impure Method is called for readonly field of value type."
Why is it saying that? And what can I do to make it go away?
It's not pure because it does not return a value dependent only on its input. When the value of X or Y changes so does the return value of ToExactLocation, i.e., its output depends on internal, mutable state.
Additionally, the setters for X or Y in ExactLocation may mutate the input. The getters of ScreenLocation may as well.
someScreenLocation is a readonly field and is a value type. You are calling ToExactLocation on a value, i.e., a readonly field. When you access a reaodnly value type a copy is created as to avoid mutating the value itself. However, your call may mutate that value, which, in many cases, is not what you want as you will be mutating a copy. This is why you get a warning.
In this case, you can ignore it, but I would avoid mutable value types in general.
EDIT:
Let me attempt to simplify...
struct Point
{
int X;
int Y;
bool Mutate() { X++; Y++; }
}
class Foo
{
public readonly Point P;
Foo()
{
P = new Point();
P.Mutate(); // impure function on readonly value type
}
}
When Mutate() is called, a copy of P is created and passed along with the method. Any mutation of P's internal state will be irrelevant as it mutates a copy.
One of the conditions of a Pure Method is that its output (return value) is wholly dependent on its input (arguments).
Your .ToExactLocation() method is not pure, because its output depends both on the input arguments and also on the current value of a mutable struct.
Resharper doesn't like this, because mutable structs are bad (don't use them). I expect the error would go away if you either changed your code to use a class instead of a struct or redesigned the struct so the the .X and .Y members could only be set by the constructor.
Reading the answer, I found out that pure functions are necessarily like functions in mathematics. f(x) = x^2 + 2x + 10 will always return 10 if x is 0.
So ToExactLocation() must return the same values each time it is called, regardless changes to object since initial creation, for it to be called "pure".
There are 2 meaning of "pure function": one theoretical (no side effects/no dependency on mutable state) and another is what ReSharper thinks about functions.
From theoretical point of view your function is not pure because it depends on mutable state. Sample:
var someScreenLocation = new ScreenLocation(1,1);
var locationOne = someScreenLocation.ToExactLocation();
var locationTwo = someScreenLocation.ToExactLocation();
someScreenLocation.X = 3;
var locationThree = someScreenLocation.ToExactLocation();
For method to be pure it can change its result only based on input (not at all as in this case since there is no arguments). But you can clearly observe that locationOne and locationTwo are the same (good sign so far), but unfortunately locationThree is different even if the input (arguments to the function) still the same.
You can make it theoretically pure by making X and Y readonly (and adding constructor).
Even after the change ReSharper will still think it is not pure - to convince it you can use Pure attribute to mark it as pure.
Note that ReSharper marks usage of "impure" functions even in constructor of the class with readonly field. Sample below shows ReSharper warnings:
struct Point
{
public int X;
public int Y;
public Point(int x, int y){X = x;Y = y;}
public void Mutate(){X++;}
public Point TheoreticallyPure(){return new Point(1, 1);}
[Pure] public Point MarkedPure(){ return new Point(1, 1);}
}
class WithReadonlyField
{
public readonly Point P;
public WithReadonlyField()
{
P = new Point();
P.TheoreticallyPure(); // impure function on readonly value type
P.MarkedPure(); // return value of pure not used
P.Mutate(); // impure function on readonly value type - modifies P.
P = new Point().MarkedPure(); // ok to modify P multiple times.
}
public void NormalMethod()
{
P.Mutate(); // impure function on readonly value type, no changes to P
}
}
C# allows modification of readonly fields up to the end of constructor, but ReSharper marks usages of all "impure" functions there too (Note that Mutate function in constructor actually changes value of readonly field P, unlike in NormalMethod where it has no effect).
"readonly... assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class"
Most likely this behavior of ReSharper is for consistency and to avoid cases where moving perfectly valid code changes behavior completely.
It would be better to model this as a static method (on either class) and would get rid of the impure warning. Explanation omitted, as the other answers covers the why already.
Example:
public static ExactLocation ToExactLocation(ScreenLocation loc)
{
return new ExactLocation {X = loc.X, Y = loc.Y};
}
or use an extension method
public static ExactLocation ToExactLocation(this ScreenLocation loc)
{
return new ExactLocation {X = loc.X, Y = loc.Y};
}
Not really sure about the cause, and I'd put this as a comment if it would format correctly...
Wouldn't you want something like:
var someScreenLocation = MethodThatGivesAScreenLocation();
if (DestinationLocation.X == someScreenLocation.ToExactLocation().X &&
DestinationLocation.Y == someScreenLocation.ToExactLocation().Y)
{
// Do stuff
}
For example
Public int Width
{
get { return Something.Width; }
}
instead of
Public int Width;
//later in the code
Width = Something.Width;
or
Public int Width = Something.Width;
Accessors are a very powerful feature, that allows you to attach methods and advanced visibility modifiers to your properties.
Fake Read-Only Example
public class Entity
{
// This Health variable looks like a read-only variable from the outside, but is still settable outside the constructor.
public Single Health { get; private set; }
// This Resistance variable looks like a read-only variable from the outside, but is still settable outside the constructor.
public Single Resistance { get; private set; }
public void Damage(Single amount)
{
this.Health -= Math.Max(amount - this.Resistance, 0.00f);
}
}
Method Example
public class Entity
{
private World world;
public World World
{
get { return this.world; }
set
{
// This will ensure the entity is always added and removed correctly from the world it is set to belong to.
if(this.world != null)
this.world.RemoveEntity(this);
this.world = value;
if(this.world != null)
this.world.AddEntity(this);
}
}
}
Advanced Visibility Example
public class Entity
{
// This gives you a read-only style property, which can still be set by other classes inheriting this class, as the setter is protected.
public Vector2 Position { get; protected set; }
}
I'm sure there are plenty of other examples, but this is some of the reasons accessors are a wonderful tool.
Note that an accessor always gets the default value, and you can only change this in the constructor.
Default values
byte, short, int, long, float, double: Zero
string: An empty string.
classes: null
structs: The default value for their members types.
1) Width is just a question you can ask about an object, how wide are you? Outside you don't really care how width is dealt with inside, you just care about what is the answer.
2) Width may change, right now it's just a width member variable but later maybe it's a calculation or maybe the object is really a list of other objects. The object itself should be responsible for all that and not someone outside who is not-the-object.
3) The less outside objects know about how and the more they only care about what the easier it is to understand code you or someone else wrote a year ago.
4) It centralizes control over the width property of that class which means that code is all in one place and easy to maintain. Any other way if something changed then code all over your program has to change, too, and that's just a big mess ;-)
5) The same goes with using setters instead of just shoving a number into Something.Width directly.
So basically it's a way of keeping the inside world of an object safe from the outside and making it really easy to change how an object works without disturbing the rest of your program.
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;
}
}
}