-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
92 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
|
||
# C# Language Design Notes for April 6th, 2020 | ||
|
||
## Agenda | ||
|
||
Init-only members | ||
|
||
## Discussion | ||
|
||
We have a proposal to dive into: https://github.com/jaredpar/csharplang/blob/init/proposals/init.md | ||
|
||
* The proposal notes that you can set `init` fields of the base type during construction, similar | ||
to `readonly`. This is not how `readonly` works today, only the declaring type can set readonly | ||
fields | ||
|
||
* The proposal allows `init` on class and struct declarations as a shorthand for `init` on types. | ||
This is different from how `readonly` struct works today, where there is no syntactic shorthand, | ||
`readonly` simply adds the additional requirement that all instance fields are marked `readonly`. | ||
|
||
* For the runtime: does this feature prohibit runtime restrictions on setting `readonly` instance | ||
fields in the future? Put simply: yes. To avoid breaking C#, the runtime would be required to | ||
either respect the proposed `InitOnlyAttribute`, or restrict optimizations to not alter the code | ||
for these features. | ||
|
||
* Use in interfaces: the proposal prohibits it, but the following example seems useful: | ||
|
||
```C# | ||
interface I | ||
{ | ||
int Prop { get; init set; } | ||
} | ||
|
||
public void MyMethod<T>() where T : I, new() | ||
{ | ||
var t = new T() { | ||
Prop = 1 | ||
}; | ||
} | ||
``` | ||
|
||
* Signature compatibility: should `init` properties be compatible with mutable ones? That is, should | ||
removing `init` in favor of a bare `set` be binary-compatible? This impacts our decisions for how | ||
we think about safety in older compilers: | ||
|
||
* If we use a modreq to prevent other compilers from unsafely using a `setter`, that affects the | ||
signature of the method, and would make the above a breaking change | ||
|
||
* If we want accept that older compilers are not a problem (C#, VB, and F# will all be updated), | ||
perhaps we don't need to specially guard this at all | ||
|
||
* We could use attributes to mark *and* guard, by using the `Obsolete` attribute. `ref struct`s | ||
use this guard by having an Obsolete attribute with a reserved message, that is ignored by | ||
compatible compilers. | ||
|
||
### Accessors | ||
|
||
Should we allow three accessors: `get, set, init`? A big problem here is that you can end up | ||
calling instance members in a constructor that invoke the setter, not the initter, for a | ||
property. This means that there are few, if any, invariants that hold for init vs. set, and | ||
weakens the feature significantly. | ||
|
||
### Syntax | ||
|
||
`init` vs. `initonly` for syntax. On the one hand, `init` is inconsistent with `readonly` (vs. `initonly`), but on the other hand we're pretty sad that `readonly` is such a long keyword. It also has few analogies | ||
with properties, where `readonly` isn't allowed at all, and the shorter `init` keyword seems more similar to | ||
`get` and `set` | ||
|
||
* Usage of `init` as a modifier: there are a number of different meanings here, and similarities | ||
between `readonly` and `init` is separating the more places we use it. For instance, if `init` is | ||
allowed as a member modifier, it seems similar to `readonly` on members, but they actually do | ||
different things. Moreover, `readonly` on types means that all instance fields and methods are | ||
`readonly`, while `init` on types would only mean `init` on fields, not on methods. | ||
|
||
* What are the uses for `init` methods, aside from helper methods? Could they be used in collection initializers? | ||
|
||
### Required Initialization | ||
|
||
The proposal in this doc is that required initialization is also an important feature for setters. We're | ||
going to leave that discussion for a future meeting. As proposed, nullable warnings are not modified for | ||
`init` members. | ||
|
||
**Conclusions** | ||
|
||
No `init` on types. No agreement on syntax. We probably have to talk about more of the use cases. | ||
We've decided that having three different accessors is not helpful. Settled that we will place a | ||
`modreq` on all `init` setters. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters