After reading some source code of different c# project i noticed different ways of writing (almost) the same statement regarding public "getter" and private "setter" properties.
First way with only properties:
public int x { get; private set; }
Second way with expression-bodied properties:
private int _x;
public int x => _x;
I know that public int x { get; } is equivalent to
private readonly int __x;
public int x { get { return __x } }
So I understand the difference between expression-bodied and normal properties in the case of a single "getter".
What i do not understand is the difference when there is a private field that holds the referenced value. I thought that maybe the second one is faster because you have access to the field directly instead of a method call inside your class.
Is it just a stylistic difference or is one of the examples faster, more robust, etc?
You have two groups of constructs which are equivalent.
Group 1
When you don't need write access to the backing field outside the constructor, you can use any of these constructs:
private readonly int _x;
public int x => _x;
or
private readonly int _x;
public int x { get => _x; }
or
private readonly int _x;
public int x { get { return _x; } }
or
public int x { get; }
Group 2
When you need access to the backing field outside the constructor, you can use any of these constructs:
private int _x;
public int x => _x;
or
private int _x;
public int x { get => _x; }
or
private int _x;
public int x { get { return _x; } }
or
public int x { get; private set; }
You can expect all of the alternatives to be equally fast. In the last construct the compiler will inject a setter method (it will inject a backer field too, as for every automatic property). In the other cases you access the field directly. The injected setter will almost certainly be inlined by the jitter, which removes the performance penalty of a method call. Check this Q&A for details on JIT inlining.
The automatic property is certainly more concise, which makes your code neater, especially when you have many properties. But at the end of the day it comes down to personal preference (or your team's coding rules).
If you use a private backing field, You are encapsulating the information and creating more robust code. It also improves the readability in some cases.
There is also the fact that the value is stored safely in a field and so if you have logic within your getters and setters that needs to change in the future it is separated from the actual value store and makes changing that implementation easier in future
Note that there's even another possibility if you initialize the property in the constructor
public int X { get; }
This is a getter-only property introduced in C# 6.0. You can assign it in the constructor (and then never again)
public MyClass (int x) // Constructor
{
X = x;
}
or with an initializer
public int X { get; } = 100;
You should not care about speed for those things. Create an easy to read and robust code. The C# compiler or the Jitter (Just In Time compiler running when the application starts, and methods are called for the first time) will possibly inline the code and not even call the getter or the setter.
The difference between normal and expression-bodied properties, methods and constructors is only of syntactical nature. There is no difference in behavior. Both variants produce the same compiled IL code and therefore, there is no difference in speed.
public int X => _x; is simply a shorter syntax for public int X { get { return _x; } }. This is also called syntactic sugar.
Related
Is there any difference between these two?
int a;
public int A
{
get => a;
set => a = value;
}
public int A { get; set; }
public int A { get; set; }
is the exact same as saying:
private int _a;
public int A
{
get => _a;
set => _a = value;
}
Auto-properties are simply syntactic sugar for a private field, and public getters and setters. It allows you to access and mutate a field (as a property) without the boilerplate of getter and setter methods. We must always encapsulate our data, and properties aim to speed up the process of writing that out
If this was java, you would have something like:
private int a;
public void setA(int a){
this.a = a;
}
public int getA(){
return a;
}
When creating classes in java, you have to by force of habit define your getters, setters, hash code, and to string methods. Of course, modern IDE's will literally generate the stock implementations of these for you, but mentally it becomes a given. If there is no special logic in any of these methods that we routinely create, why be forced to write it out? Auto-props aim to take away a bit of the hassle. It just a quality-of-life bit of syntax for cleaner looking code. It tells you upfront that you have the stock accessors and mutators out of the box
Its also quite modular, take a look at the documentation to see how you can make for things like private setters, use init for immutability post-obj construction, etc
Its almost always preferable to use public properties over public fields in C#, easiest way to remember is: private fields, properties for any access mod above that
I have a simple class that represents 3 dimensional coordinates called Coord3 that simply has x, y, and z int values.
I want to declare a static constant variable Coord3.zero where x, y, and z are set to 0.
I have attempted this with:
public static readonly Coord3 zero = new Coord3(0, 0, 0);
However I found that this variable can be changed. For example if I do
Coord3 coord = Coord3.zero;
coord.x = 5;
this actually changes the x value of Coord3.zero to be 5. Maybe I am misunderstanding readonly? I know that in Unity there is Vector3.zero which never changes. I am trying to achieve the same effect.
Maybe I am misunderstanding readonly?
Yeah, readonly means you can't change the reference of your variable. In other words, you can't write Coord3.zero = new(...);
Now, the way these things are usually written is as structs, where fields are by default immutable. That would solve your problem right there. That is also how it's done in Unity. Note that you can also do this with classes, by having only getters on your properties and filling them in once from your constructor, but classes are very heavy weight for these small types.
readonly is not quite the same thing as immutable in the sense you mean. readonly means you cannot assign to a variable. So you couldn't do
public static readonly Cord3 zero = new Cord3(0, 0, 0);
zero = new Cord3(0, 0, 1);
In order to achieve the effect you want, you could need to create a class, struct or record with readonly properties or fields. There's no way to achieve that effect with a type defined in an internal library. If the type allows mutability on a field or property, that field or property is mutable.
Marking zero as readonly indeed prevents you from changing what zero stores. You cannot reassign it.
zero = new Coord3(1, 1, 1); // error
Note that since Coord3 is a class, zero.x = 5; isn't actually changing what zero stores. You are just changing some property of the object that zero is referring to. zero is still storing the same reference to the same old object.
You could prevent this by not providing any public API in Coord3 that would change its fields' values - for example, by making x, y, z all read-only properties:
public int X { get; }
public int Y { get; }
public int Z { get; }
Of course, this wouldn't work if you just want to prevent setting the properties on zero, but allow the modification of Coord3 on other objects.
I would suggest that you make Coord3 a struct:
public struct Coord3 {
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
}
Now zero stores the fields' values directly, rather than a reference to an object. zero.x = 5; would produce an error, because you are modifying what zero directly stores.
Note that Unity's Vector3 for example, is also a struct.
I think you can make an immutable base class and your Coord3 inheriting this class.
public class BaseCoord3
{
// protected means it can only be used by BaseCoord3 and Coord3
protected int x;
// equivalent to public int X { get { return x; } }
public int X => x;
}
public class Coord3 : BaseCoord3
{
public override int X
{
get { return x; }
set { x = value; }
}
public static BaseCoord3 Zero => new BaseCoord3(0,0,0);
}
This should work similar to the way with Readonly versions of collections in c#. I think the struct solutions are the way to go though.
How about you just use a get-property to never change the zero object?
public class Coord3
{
public static Coord3 Zero => new Coord3(0,0,0);
}
Then you won't be able to change the values of Zero, but you will maintain the functionality of Coord3 objects.
Coord3 a = Coord3.Zero;
a.x = 2; // changes a.x, but not Coord3.Zero.x
Private Samples As Collection
Public Function Count() As Integer
Count = Samples.Count
End Function
I am trying to translate this code into C#. I am also trying to understand this code's logic. I currently have this code,
Public int Count {get; set;}
This is written in c#.
No, if it says Function, it means function. Conversely, if it said Property it would be a property and could then (optionally) only contain a getter.
The precise equivalent is:
public int Count() {
return Samples.Count;
}
Where you may have been tripped up is looking at the calling code - in VB, the parentheses are optional when calling a parameterless function, so you may see code that invokes the above function just saying Count rather than Count().
private Collection<object> Samples { get; set; }
public int Count() {
return Samples.Count;
}
This is the equivalent implemented as a Property (Like you tried to do):
public int Count
{
get
{
return Samples.Count;
}
}
The exact equivalent : As a normal method you would do this:
public int Count()
{
return Samples.Count;
}
However, the below code creates a default setter and getter. You don't need a setter in your case, and the getter doesn't return the value of _count hidden field. But it returns the count of the list.
Public int Count {get; set;}
Those are auto-implemented properties which are equivalent to:
private int _count;
public int get_Count()
{
return _count();
}
public void set_Count(int value)
{
_count = value;
}
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.
Assuming I have a struct:
struct Vector
{
public int X, Y;
// ...
// some other stuff
}
and a class:
class Map
{
public Vector this[int i]
{
get
{
return elements[i];
}
set
{
elements[i] = value;
}
}
private Vector[] elements
// ...
// some other stuff
}
I want to be able to do something like: map[index].X = 0; but I can't, because the return value is not a variable.
How do I do this, if at all possible?
You should avoid mutable structs.
If you want your type to be mutable use a class instead.
class Vector
{
public int X { get; set; } // Use public properties instead of public fields!
public int Y { get; set; }
// ...
// some other stuff
}
If you want to use a struct, make it immutable:
struct Vector
{
private readonly int x; // Immutable types should have readonly fields.
private readonly int y;
public int X { get { return x; }} // No setter.
public int Y { get { return y; }}
// ...
// some other stuff
}
The compiler prevents you from doing this because the indexer returns a copy of an object not a reference (struct is passed by value). The indexer returns a copy, you modify this copy and you simply don't see any result. The compiler helps you avoid this situation.
If you want to handle such situation you should use class instead or change the way you deal with Vector. You shouldn't modify it's value but initialize it's values in constructor, more on this topic: Why are mutable structs “evil”?.
define Vector as class,
or
store value in a temporary variable
var v = map[index];
v.X = 0;
map[index] = v;
or
add function to change
map[index] = map[index].Offset()
or
let the [] operator return a setter class
class Setter { Vector[] Data; int Index; public double X { get { return Data[Index]; } set { Data[Index] = new Vector(value, Data[Index].Y); }}}
public Setter this[int i]
{
get
{
return new Setter() { Data = elements, Index= i };
}
}
Although generic classes work pretty well for many purposes, they do not provide any reasonable way to access structs by reference. This is unfortunate since in many cases a collection of structs would offer better performance (both reduced memory footprint and improved cache locality) and clearer semantics than a collection of class objects. When using arrays of structs, one can use a statement like ArrayOfRectangle[5].Width += 3; with very clear effect: it will update field X of ArrayOfRectangle[5] but it will not affect field X of any other storage location of type Rectangle. The only things one needs to know to be certain of that are that ArrayOfRectangle is a Rectangle[], and Rectangle is a struct with a public int field X. If Rectangle were a class, and the instance held in ArrayOfRectangle[5] had ever been exposed to the outside world, could be difficult or impossible to determine whether the instance referred to by ArrayOfRectangle[5] was also held by some other code which was expecting that field X of its instance wouldn't change. Such problems are avoided when using structures.
Given the way .net's collections are implemented, the best one can do is usually to make a copy of a struct, modify it, and store it back. Doing that is somewhat icky, but for structs that aren't too big, the improved memory footprint and cache locality achieved by using value types may outweigh the extra code to explicitly copy objects from and to the data structures. It will almost certainly be a major win compared with using immutable class types.
Incidentally, what I'd like to see would be for collections to expose methods like:
OperateOnElement<paramType>(int index, ref T element, ref paramType param, ActionByRef<T,paramType> proc) which would call proc with the appropriate element of the collection along with the passed-in parameter. Such routines could in many cases be called without having to create closures; if such a pattern were standardized, compilers could even use it to auto-generate field-update code nicely.