Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open questions in Required Members #5945

Closed
333fred opened this issue Mar 23, 2022 · 3 comments
Closed

Open questions in Required Members #5945

333fred opened this issue Mar 23, 2022 · 3 comments
Assignees
Labels
Proposal Question Question to be discussed in LDM related to a proposal

Comments

@333fred
Copy link
Member

333fred commented Mar 23, 2022

Should SetsRequiredMembers be automatically emitted for record copy constructors?

We have a couple of options here:

  1. Never emit. This will have very little impact on user code today: copy constructors are protected and only accessed via withers. However, if we ever end up allowing records and classes to cross-inherit, this could have negative impacts.
  2. Always emit. This will emit new attributes for existing code if recompiled, but adding required members to a base type doesn't cause new attributes to be emitted on a derived type on recompile.
  3. Emit when this type or a base type has required members. This means that if a base type adds required members, a derived type will add SetsRequiredMembers to it's copy constructor on recompile.

Should SetsRequiredMembers suppress errors when required members lists can't be understood?

The spec today suggests that it should: for example, if we see some metadata that hides a required member, the only callable constructors would be constructors attributed with SetsRequiredMembers. Do we like this behavior, or should we block construction entirely when required members cannot be understood? This can impact base calls, both in user-written code (ie, deriving from such a type) and it can affect record copy constructors. Options:

  1. Always error if the required members list cannot be understood. This means that users could not derive from such a type, but it will cause us to do more work: we can't short-circuit evaluating the required members list when a constructor has SetsRequiredMembers, because we'll need to be sure the list is valid. It will produce the most consistent results, however.
  2. Allow calling constructors with SetsRequiredMembers always, no matter if the base list is bad. This option gives users an escape hatch, but the only way they'll get into this scenario is via manual construction of such types in IL or a language that won't block manual application of System.Runtime.RequiredMemberAttribute.

Unsettable members

Should we block applying required to members that are not settable? For example:

class C
{
    public required readonly int Field;
    public required int Prop1 { get; }
}

Options:

  1. Do not block. Such types will be unconstructable unless SetsRequiredMembers is applied to a constructor.
  2. Require that all members marked with required are either mutable fields at least as visible as the containing type, or properties with a setter/initer that is at least as visible as the containing type.

Ref returning properties

Based on the result of the previous question, is this ok?

class C
{
    private int i;
    public required ref int Prop => ref i;
}

Options:

  1. Not ok. required cannot be applied to to ref-returning properties.
  2. Ok. required can be applied to ref-returning properties, and such properties must be assigned by an object initializer.

Obsolete Members

Is it permissible to put required on an obsolete member?

class C
{
    [Obsolete]
    public required int Field;
    [Obsolete]
    public required int Prop1 { get; set; }
}

Options (First order):

  1. Ok. No action.
  2. Not ok. Always a warning or error.
  3. Not ok unless already in an obsolete context. For example, if the containing type is Obsolete, then it is ok, otherwise a warning or error.

Options (Second order, assuming first order is 2 or 3):

  1. Warning
  2. Error
@333fred 333fred added the Proposal Question Question to be discussed in LDM related to a proposal label Mar 23, 2022
@333fred 333fred self-assigned this Mar 23, 2022
@TonyValenti
Copy link

I personally like the ability to make private/protected, setter-only property required. I would use this to clarify intent that my constructors absolutely should set that property. This way if I add another constructor, I am required to provide it. I kind of think that would be similar in usage to a base(x) call.

@333fred
Copy link
Member Author

333fred commented Mar 23, 2022

@TonyValenti it wouldn't require that. There is no way, in the current proposal, to require that a constructor body set a property.

@333fred
Copy link
Member Author

333fred commented Mar 23, 2022

@333fred 333fred closed this as completed Mar 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Proposal Question Question to be discussed in LDM related to a proposal
Projects
None yet
Development

No branches or pull requests

2 participants