Replies: 14 comments 2 replies
-
See #318 - we discussed read only properties. We discussed at the end a new keyword / accessor, because 'read only' is a bit of a misnomer. Note: Doing everything in the constructor is a code smell. Complex initialization is OK but lengthy computation would not - your design esp. read only methods encourage the latter. Think about the type of exceptions a developer would reasonably expect from a constructor call. |
Beta Was this translation helpful? Give feedback.
-
In your example you demonstrate setting a
C# has never required that all of this is done in the constructor. Only that the assignment of |
Beta Was this translation helpful? Give feedback.
-
I'm really struggling to see the point of this proposal. Maybe I'm just stuck on the oxymoron of "readonly setters" and that it could just be that "readonly" is the wrong term to use. |
Beta Was this translation helpful? Give feedback.
-
@DavidArno During the development process this would allow to outsource initialization logic to dedicated methods that e.g. need to set more than 1 field. Or the code can be moved to, and therefore being near to the corresponding property. The constructor can be kept nice and short. When the calculation gets too complex, it shouldn't be done in the constructor anyhow. As the corresponding calculation may already be in a dedicated method, refactoring might be easier. For "readonly" properties maybe the CLR can check whether the setter of a property is only called once and thus ensuring the safe use. In the code, a readonly property can only be accessed from the object initializer. As the initializer is called after the construction, lengthy operations can be assigned there (and it looks good, too). So the former readonly method that was called by the constructor can now be converted to or called by the setter (with a little modification). The CLR and language design toghether ensures that we are still in the initialization phase. |
Beta Was this translation helpful? Give feedback.
-
I would support a proposal that's somewhat similar to this: It sort of crosses over with the idea of a method being pure, but not exactly. This also sort of crosses over with immutable classes, which I've seen before in the repo of issues but for some reason I'm struggling to find right now. Basically an immutable class would be a class where all the methods / properties are @lachbaer I think this gives you a lot of the behaviour you want, but with a slightly less confusing use of the work It would kind of be like Swift's |
Beta Was this translation helpful? Give feedback.
-
Maybe, I have already seen some lengthy constructors, that do several work but no 'costly' things. Those constructors are absolutely fine, though having many lines of code. This proposal could help to tidy this up a bit, especially when a single assignment would complicate things, because there are dependencies between different readonly fields. Also things like |
Beta Was this translation helpful? Give feedback.
-
Couldn’t you just make your This sort of thing seems confusing to me. In many cases you might just write a static method that performs the complicated computations and then passes the result to a If you wanted this feature, instead of changing the CLR’s |
Beta Was this translation helpful? Give feedback.
-
Okay, yes....
Wait what? Classically, doesn't make a lot of sense to set more than one field at a time, but I can see if you have two properties being related but one can't be derived from the other (for whatever reason), but it would be entirely possible to do so now with Tuples without needing any sort of new syntax. public class Foo
{
public int One { get; }
public int Two { get; }
public string Three { get; }
public Foo(int one, int two, string three)
{
// don't think you can deconstruct straight into properties,
// so using a temp to hold the deconstruction
var (i, j) = ValidateCombination(one, two);
// constructor is still in charge of the actual assignment
One = i;
Two = j;
// and a single validation can be assigned directly into the property
Three = ValidateThree(three);
}
private static (int i, int j) ValidateCombination(int one, int two)
{
// .....
return (one, two);
}
private static string ValidateThree(string three)
{
// .....
return three;
}
} |
Beta Was this translation helpful? Give feedback.
-
How about IL emit at runtime? How about IL assembler? Compiler for another language? Type safety at runtime-level would be compromised if safety would be "ensured" by C# compiler only. |
Beta Was this translation helpful? Give feedback.
-
I actually really like such an idea. Maybe it is bad design on my part, but I sometimes have properties that don't have an initial value, are not lazy, and are meant to be written once often externally. For example interface IModifiable<TModifiable, TModifier> where TModifier: IModifier<TModifiable>
{
void ModifyWith(TModifier modifier)
TModifier Modifier { get; }
} Granted, it would be better to use an immutable type and simply return a new object as in interface IModifiable<TModifiable, TModifier> where TModifier: IModifier<TModifiable>
{
TModifiable ModifyWith(TModifier modifier)
TModifier Modifier { get; }
} but this is not always desirable. |
Beta Was this translation helpful? Give feedback.
-
Can't you use local functions though and use |
Beta Was this translation helpful? Give feedback.
-
Well, since other issues opened regarding this matter have been closed, and there's been 3 years since last activity here, I'm curious as to whether there is any plans on doing something similar |
Beta Was this translation helpful? Give feedback.
-
If you use Rx you have this problem often, because constructors get quite long. |
Beta Was this translation helpful? Give feedback.
-
I am looking for something like this, it makes the language richer and more expressive. Also it works well for source code generators that generate constructors but you cant put custom logic on it and you need to put it in a Validation or Initialize method (nowdays you loose wirte access to readonly fields). |
Beta Was this translation helpful? Give feedback.
-
readonly
methods and properties for initializationContinuation of Proposal: read-only setter (again) (dotnet/roslyn#13048)
Intent
The
readonly
modifier currently only allows to let the corresponding fields be set in the direct constructor body only.This proposal extends the usage of
readonly
to be used in other places as well.That should allow for more modular code where e.g. a constraint for a property is checked in its setter.
Behaviour and constraints
Methods and properties can also be decorated with the
readonly
keyword.Methods
readonly
methods can only be called byreadonly
methods (thus indirectly belonging to the constructor)Obviously
public
andinternal
methods don't make sense.readonly
properties - setter and maybe getter?Properties
readonly
properties can only be setreadonly
methodsreadonly
properties - setter and maybe getter?Motivation
This would require a CLR change to hoist the meaning of
readonly
.In essence, from the CLR point of view,
readonly
will allow to changereadonly
fields from every method that is also decorated asreadonly
.The compiler ensures that the above mentioned constraints will be met. That will make sure that readonly fields can still only be initialized from the constructor or the directly following initialization part.
Syntax
Following bogus example shows the usage:
Issues
Malicious emitters
Can malicious emitters produce MSIL that calls
readonly
methods or setters from other places than the constructor or initializer? The CLR would not recognize that as long as everything is decorated withreadonly
.The CLR ensures that the caller also is
readonly
or the constructor. But forreadonly
properties only the compiler restricts its use to the initializer.Parent of initializer call
The parent of the initializer calls to
set_Xxx(value)
is notreadonly
. The CLR must skip the readonly-verification for setters.Beta Was this translation helpful? Give feedback.
All reactions