Do these statements mean the same thing?
int x { get; }
readonly int x;
In answer to your question: There is a difference between readonly and {get; }:
In int x { get; } (which won't compile as there's no way to set x - I think you needed public int x { get; private set; } ) your code can keep changing x
In readonly int x;, x is initialised either in a constructor or inline and then can never change.
readonly int x; declares a readonly field on a class. This field can only be assigned in a constructor and it's value can't change for the lifetime of the class.
int x { get; } declares a readonly auto-implemented property and is, in this form, invalid (because you'd have no way whatsoever to set the value). A normal readonly property does not guarantee to return the same value every time it is called. The value can change throughout the lifetime of the class. For example:
public int RandomNumber
{
get { return new Random().Next(100); }
}
This will return a different number everytime you call it. (Yes, this is a terrible abuse of properties).
No, the statements do not mean the same thing. The full version of the property will have a backing variable:
private int _x;
public int X
{
get { return _x; }
}
Another method in the class could modify the backing variable, changing the value of the property:
private void SomeMethod(int someValue)
{
_x = someValue * 5;
}
The readonly keyword only allows a member variable to be assigned in its declaration or in the constructor:
// Both of these compile
private readonly int _x = 1;
public SomeClass()
{
_x = 5;
}
// This will not compile
private void SomeMethod(int someValue)
{
_x = someValue * 5;
}
So a get-only property whose backing variable is marked readonly is a true read-only property.
Other answers are sorta outdated…
In newer versions of C# you can assign a default value to int x { get; } = 33; which changes things.
Basically, it gets compiled down to get-only property with a readonly private backing field. (See https://softwareengineering.stackexchange.com/q/372462/81745 for more details)
Another difference I see is that you can't use the readonly version when using interfaces as you can only define methods and properties.
readonly keyword is making sure that these variables dont change once initialised // it is equalant to making a variable private and setting getter for it.
Example.
public class PlayerAuthData
{
public readonly string emailId, password, userName;
private string hello;
public PlayerAuthData(string emailId, string password, string userName)
{
this.emailId = emailId;
this.password = password;
this.userName = userName;
}
public string Hello
{
get { return hello; }
set { hello = value; }
}
}
public class AuthManager
{
void Start()
{
PlayerAuthData pad = new PlayerAuthData("a#a.com", "123123", "Mr.A");
pad.Hello = "Hi there";
print(pad.Hello);
print(pad.password);
print(pad.emailId);
print(pad.userName);
}
}
Literally, there's no big difference because you've declared x to be private (the default). You can always re-compile your class to make x different.
However, if it were public, the definition public int x { get; } allows you to later expand the definition to something like this:
int x { get {
return DoSomeOperation();
}
}
You can do that without breaking your clients. The implementation of the getter is private and clients call it without knowing if it is a static value or has an operation inside its get accessor.
Propery can have backing variable that can be set using any method of that class
private int a;
public int A{get;}
public void ChangeAMethod(int value){
a=value;
}
However readonly fields can only be assigend in constructor or in-line.
Related
Perhaps this question some of you have no meaning to it, but I am baffled if any of you can answer me.
Assuming that I have this structure and it has a field or several fields for reading only, how can I assign a value to it through the constructor.
struct PointWithReadOnly
{
// Fields of the structure.
public int X;
public readonly int Y;
public readonly string Name;
// Display the current position and name.
public readonly void Display()
{
Console.WriteLine($"X = {X}, Y = {Y}, Name = {Name}");
}
// A custom constructor.
public PointWithReadOnly(int xPos, int yPos, string name)
{
X = xPos;
Y = yPos;
Name = name;
}
}
To use this struct, add the following :
PointWithReadOnly p1 = new PointWithReadOnly(50,60,"Point w/RO");
p1.Display();
The field is read-only, so how does the code work in this way?
Because readonly field can be assigned either when declared, or in it's class constructor
Assume I've defined an interface with multiple properties, e.g.:
interface IFailable<T>
{
T Value { get; }
bool Success { get; }
}
and I want class Foo to expose multiple readonly instances of this, where IFailable properties are calculated from Foo's private non-static data, how would I do that in c#?
In Java its fairly intuitive.
Here's the best I came up in c#, based on https://stackoverflow.com/a/4770231/146567
First create a wrapper:
public class FailableDelegator<T> : IFailable<T>
{
public delegate T valueDelegate();
public delegate bool successDelegate();
private readonly valueDelegate valueHandler;
private readonly successDelegate successHandler;
public T Value { get { return valueHandler(); } }
public bool Success { get { return successHandler(); } }
public FailableDelegator(valueDelegate v, successDelegate s)
{
valueHandler = v;
successHandler = s;
}
}
Then use it to define the properties in Foo's constructor:
public class Foo
{
private double x = 3;
private double y = -9;
public readonly FailableDelegator<double> xPlusY;
public readonly FailableDelegator<double> sqrtY;
public Foo()
{
xPlusY = new FailableDelegator<double>(() => x + y, () => true);
sqrtY = new FailableDelegator<double>(() => Math.Sqrt(y), () => y>=0);
}
}
I had to put the definitions in Foo's constructor because I got error "cannot access non-static field in static context" if I attempted it directly on the field.
I'm not keen on this, because for less trivial examples you end up with a huge amount of code in Foo's constructor.
Using c# auto-implemented properties can I have a class that does the following (psuedo C# code because I get an error - which is below when trying to compile this):
public class Foo {
public String HouseName { get; private set; }
public int HouseId { get; private set; }
public int BedsTotal {
get { return (BedsTotal < 0) ? 0 : BedsTotal; }
private set;
}
}
Error 5 'House.BedsTotal.set' must declare a body because it is not marked abstract, extern, or partial c:\src\House.cs
To me it seems like I should be able to get a body for the getter and rely on the private set being auto-generated like it would be if I did a { get; private set; } but that's not working.
Do I need to go the whole way and set up member variables, take the private setter off, and use the members vars instead?
Thanks!
Yes, you'll need to set up private variables because at the moment you will end up in a loop trying to read the get {} portion because it references itself.
Set up a private backing variable like this:
private int _bedsTotal;
public int BedsTotal {
get { return (_bedsTotal < 0) ? 0 : _bedsTotal; }
private set { _bedsTotal = value; }
}
Then you can access beds through the private setter
i whould go for an even more easier approach
private int _bedsTotal;
public int BedsTotal
{
get
{
return (this._bedsTotal < 0) ? 0 : this._bedsTotal;
}
private set
{
this._bedsTotal = value;
}
}
and so you can set the value of BedsTotal like this : this.BedsTotal = [integer];, no need to used other private methods since you can make use of the set
I have a class with 5-6 fields that should be initialized once after the constructor runs.
public OriginalFileProcessor(IConfigManager configManager)
{
this._configManager = configManager;
this._field1 = this._configManager.GetAppSetting<int>ConfigKeys.Key1);
this._field2 = this._configManager.GetAppSetting<int>ConfigKeys.Key2);
this._field3 = this._configManager.GetAppSetting<int>ConfigKeys.Key3);
this._field4 = this._configManager.GetAppSetting<int>ConfigKeys.Key4);
this._field5 = this._configManager.GetAppSetting<int>ConfigKeys.Key5);
}
But I don't like to write logic apart from just simple assignments in the constructor.
I can't use inline initialization for field1 for example since then I can't use the _configManager instance there:
private int readonly _field1 = this._configManager.GetAppSetting<int>ConfigKeys.Key1);
If I use a readonly property then I'd have to add extra code like this:
private int? _field1;
public int Property1
{
get
{
if (!this._field1.HasValue)
{
this.__field1 = this._configManager.GetAppSetting<int>(Key1);
}
return this._field1.Value;
}
}
Is there any simpler approach for late initialization of instance fields?
Lazy<T> is a good option as suggested.
What I usually use is the following...
Providing your _field* is a nullable
In your property you can do...
return this.__field1 ?? (this.__field1 = this._configManager.GetAppSetting<int>(Key1));
EDIT:
Given comments discussion - why not just use a non static approach over Lazy<T>, e.g.
private readonly Lazy<int?> _field;
// init in ctor
_field = new Lazy<int?>(() => YourFieldInit(""));
// use in property
return _field.Value ?? 0;
EDIT 2:
And a small test to clarify the Lazy behavior:
public class DoLazy
{
Lazy<int?> _field;
public DoLazy()
{
// 'lazy' gets initialized - but `YourFieldInit` is not called yet.
_field = new Lazy<int?>(() => YourFieldInit(""));
}
int Property
{
get
{
// `YourFieldInit` is called here, first time.
return _field.Value ?? 0;
}
}
int? YourFieldInit(string test)
{ // breakpoint here
return -1;
}
public static void Test()
{
var lazy = new DoLazy();
int val1 = lazy.Property;
var val = lazy.Property;
}
}
Put a breakpoint inside the YourFieldInit - to see when it's actually called.
Call DoLazy.Test() from your e.g. Main.
I'm trying to create a class which takes value a as a parameters in it's constructor.
It has a private member variable which stores this value. The value should not be changed afterwards.
Here's what I have, it works but I don't think it's the best solution out there:
internal class Foo
{
private int a;
public int A
{
get
{
return this.a;
}
}
public Foo(int a)
{
this.a = a;
}
}
So this way you can not access a from outside of the class, and A-property only has a get method. However, you can still change a from inside the class, and using a property which only returns one variable and nothing else feels stupid.
Am I doing this right, or is there a way to improve my code/more proper way to do this?
Additionally declare your private field readonly and you're there!
public class Foo
{
public Foo(int bar)
{
this.bar = bar;
}
public int Bar
{
get
{
return bar;
}
}
private readonly int bar;
}
“In C# 6 and later, you can initialize auto-implemented properties similarly to fields”. Just like you can initialize a readonly field in a constructor, you can initialize a get-only auto-implemented property in a constructor. Thus, the following now compiles:
public class Class1
{
public int A { get; }
public Class1(int a)
{
A = a;
}
}
…and the following yields an error:
public class Class1
{
public int A { get; }
public Class1(int a)
{
A = a;
}
public void Mutate()
{
// Class1.cs(11,9,11,10): error CS0200: Property or indexer 'Class1.A' cannot be assigned to -- it is read only
A++;
}
}
I like it—you get the terseness of field initialization with the interface/OOP-friendliness of properties.
internal class Foo
{
private readonly int _a;
public int A
{
get
{
return _a;
}
}
public Foo(int a)
{
_a = a;
}
}
This should do it.