meetings/2022/LDM-2022-05-02.md
SetsRequiredMembers on nullable analysishttps://github.com/dotnet/csharplang/issues/3630
https://github.com/dotnet/csharplang/issues/6081
We have an open question on required properties: what should the effect of SetsRequiredMembers be on nullable analysis? Should the property be taken as a tool to silence
the compiler, or should it restore the nullable warning to the current constructor?
A key insight of required as a feature is that is orthogonal to nullable. It can move where a nullable warning is reported, but it does not suppress the warning: assigning
a not-null reference type property to null will still produce a warning. If SetsRequiredMembers started actually suppressing the nullable warning, that would mean that
this orthogonality is lost, and the two features become more entangled that we would otherwise want. While there could be some users confused why we aren't also warning or
erroring on nullable or value type members that aren't set in the constructor, we think the right decision is to have SetsRequiredMembers move the nullable warning back to
the constructor, rather than suppressing it completely.
Nullable warning will be moved back to the constructor when SetsRequiredMembers is applied.
field questionshttps://github.com/dotnet/csharplang/issues/140
https://github.com/dotnet/csharplang/issues/6076
https://github.com/dotnet/csharplang/issues/6077
First up in semi-auto properties, we have a couple of questions about the behavior of overriding a virtual property with a semi-auto property. There existing rules in C# that prevent an auto-property from overriding only one accessor of a virtual property, as it's a potential footgun in waiting. There are two possible viewpoints here:
After some discussion, we're concerned that the footgun the rule exists to prevent is still here for semi-auto properties. We're also concerned about what the meaning of this code is:
class Base
{
public virtual int Prop { get; set; }
}
class Derived : Base
{
public override int Prop { get => field; }
public Derived()
{
Prop = 1; // Does this call the setter from Base? Or does it assign to the backing field in Derived?
}
}
We don't have a good answer for what this code does: by the specification, it should likely assign to the backing field. But either behavior is surprising.
We also had a small side conversation on whether we should have done work with auto properties when they were first introduced to allow them to share storage across virtual hierarchies, but there are issues with this. If this could be done across assembly boundaries, it would be exposing that you have an auto-property as a part of the public contract of a type, and that breaks the encapsulation that properties provide.
Semi-auto properties must override all accessors of a base property.
https://github.com/dotnet/csharplang/issues/6080
In C# 11, we are changing structs to automatically default initialize fields if the struct is read before all fields are assigned, and we need to decide if this behavior should apply to semi-auto properties as well. Our options are:
For option 1, we don't think this is the right time to introduce cross-method analysis into C#. It would bring with it all the complexity of cross-method analysis for very little benefit; if we were going to introduce cross-method analysis, there are areas such as nullable analysis that would have the exact same set of problems, but would be much more beneficial. For option 3, we note that the uninitialized struct warning is not turned on by default, and users have to opt into it. For these users, there is indeed nothing that can be done about the warning except providing an explicit property initializer, or not using the feature. Most C# users will never see the warning, and for those that do care, they should be aware of it in this case too.
Default initialize when calling a manually implemented semi-auto property setter, and issue a warning when doing so, like a regular property setter.