meetings/2022/LDM-2022-04-25.md
ref readonly method parametersref readonly method parametershttps://github.com/dotnet/csharplang/issues/6010
In another lowlevel session, we looked at a feature designed to address pain points in the BCL with in. For the most part, in works quite
well. However, there are a few APIs that have been reluctant to adopt in because of two main reasons:
in allows, is an anti-pattern and should be disallowed for a subset of APIs. This part could be addressed in an
analyzer.in requires that in be specified at the callsite for lvalues, not ref. For APIs that would want to move, such as QueryInterface, the
source-breaking change of moving to in is undesirable, and blocks adoption of the feature. This is not addressable by an analyzer.We think that we've left ourselves room in the middle between ref and in for a ref readonly feature, where in can be thought of as
ref readonly plus an additional feature of allowing rvalue parameters.
As part of this, we re-examined the motivation behind in allowing rvalues, and behind not allowing ref to be used for in parameters.
Rvalues were allowed because the similar feature in Midori originally didn't allow rvalues, and that proved painful for devs in that environment.
That environment also had an advantage of being entirely new code: migrating from ref to in or another keyword as a source-break wasn't nearly
the pain point it is for the BCL and C#, which has 20-year-old code still in use today.
We therefore believe there is space for two changes to ease the migration path:
in and ref to both be used at the callsite for in parameters. in will still be preferred, and a warning will be issued when using
ref for such cases, but this will allow a migration path that doesn't completely break consumer code, and the warning can be disabled for
codebases that don't want to update.ref readonly,
or using an attribute like LvalueOnly, effectively making it an analyzer. After some discussion, we prefer it being ref readonly: it's a
language feature, not an analyzer, so it should look like one. We will error when an rvalue is passed to a ref readonly parameter. Both ref
and in will be usable at the callsite, but use of ref will warn, like it will for in parameters.Feature is accepted. The syntax will be ref readonly. ref will be usable for both ref readonly and in parameters at the callsite, but a
warning will be issues for such cases. Passing an rvalue to a ref readonly parameter is an error.
https://github.com/dotnet/roslyn/issues/60885
Previously, we relaxed restrictions around non-public interface methods. Unfortunately, this now leaves us with inconsistencies around internal interface methods: implementations of the interface in another assembly end up implementing such internal methods implicitly, even when they lack visibility. This is particularly bad for virtual, non-abstract members, where an interface could be perfectly legal to implement in another assembly, and then adding an internal virtual method could cause that other assembly type to end up overriding an interface member it did not intend to.
In general, we dislike all of the proposed solutions here. Checking to make sure that methods aren't implicitly implementing interface methods doesn't solve the issue when the dependent assembly doesn't recompile. Relaxing the restriction for explicit implementations seems to fly in the face of accessibility in C#. Trying to emulate the exact behavior of class types has a number of holes in it. We think we need to brainstorm more about what to do here.
No action today. We will go back to the drawing board and revisit.