Sometimes I would like to declare a property like this:
public string Name { get; readonly set; }
I am wondering if anyone sees a reason why such a syntax shouldn’t exist. I believe that because it is a subset of “get; private set;”, it could only make code more robust.
My feeling is that such setters would be extremely DI friendly, but of course I’m more interested in hearing your opinions than my own, so what do you think?
I am aware of ‘public readonly’ fields, but those are not interface friendly so I don’t even consider them. That said, I don’t mind if you bring them up into the discussion
Edit
I realize reading the comments that perhaps my idea is a little confusing. The ultimate purpose of this new syntax would be to have an automatic property syntax that specifies that the backing private field should be readonly. Basically declaring a property using my hypothetical syntax
public string Name { get; readonly set; }
would be interpreted by C# as:
private readonly string name;
public string Name
{
get
{
return this.name;
}
}
And the reason I say this would be DI friendly is because when we rely heavily on constructor injection, I believe it is good practice to declare our constructor injected fields as readonly.
9
The C# team has considered that this would be a very useful feature, and that’s why in C# 6, they implemented it (just a little different from your proposal).
Getter-only auto-properties
This new kind of properties are getter-only, but can be set either inline or in the constructor. This means they are backed internally by a readonly field.
Instead of declaring a property as readonly set
, you simply not declare it.
Inline assignment
public class Customer
{
public string First { get; } = "Jane";
public string Last { get; } = "Doe";
}
Constructor assignment
public class Customer
{
public string Name { get; }
public Customer(string first, string last)
{
Name = first + " " + last;
}
}
You can read about this and other new features of C# 6 in the Roslyn wiki in GitHub.
3
As mentioned in the comments, properties are just syntactic sugar. When they are turned into methods, “readonly” would no longer be syntactically correct.
You can expose a private variable through a read-only property for the desired effect:
private readonly string _name;
public string Name {
get {
return _name;
}
}
public MyObject(string injectedName) {
_name = injectedName;
}
Edit:
How do you envision your idea would work (if it was possible)? Your readonly property wouldn’t work in an initialization list because the constructor is already finished executing at that point.
4
I think your problem is that you’re automatically assuming a getter for each injected property.
Auto-properties with private setters are for types where you have
public class Person
{
public string Name { get; private set; }
public int Age { get; private set; }
public Person (string name, int age)
{
Name = name;
Age = age;
}
}
and very little logic. This means it doesn’t matter if you can, technically speaking, set your auto-properties outside of the constructor. You probably won’t. And, as far as an external class goes, you’re still immutable.
But you don’t use DI to generate objects like this one.
You use DI to inject services that you apply logic to, like this:
public Foo : IFoo
{
private IBar _bar;
private IGrommit _grommit;
public Foo(IBar bar, IGrommit grommit)
{
_bar = bar;
_grommit = grommit;
}
public string GrommitMyBarForAName()
{
return _grommit.DoStuff(bar).Name;
}
}
In these cases, you should not automatically add an accessor for _bar, just because you can. You don’t want to give public access to it, not even readonly.
There will be cases when you feel you have to but, in those cases, you should first reconsider your design. It’s probably wrong.
If you’re absolutely positive that you should, then add a standard accessor, but this should not be a common enough situation that you feel a need to complain that there should be a syntax to allow you to have an auto-property for it.
9