4.3 KiB
C# Language Design Meeting for Apr 25th, 2022
Agenda
ref readonly
method parameters- Inconsistencies around accessibility checks for interface implementations
Quote of the Day
- "The group you're talking about just raised their hand"
Discussion
ref readonly
method parameters
https://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:
- Passing an rvalue, which
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 thatin
be specified at the callsite for lvalues, notref
. For APIs that would want to move, such asQueryInterface
, the source-breaking change of moving toin
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:
- Allow
in
andref
to both be used at the callsite forin
parameters.in
will still be preferred, and a warning will be issued when usingref
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. - Have a language feature to prevent rvalues being passed where they don't belong. We looked at two possible syntaxes for this:
ref readonly
, or using an attribute likeLvalueOnly
, effectively making it an analyzer. After some discussion, we prefer it beingref readonly
: it's a language feature, not an analyzer, so it should look like one. We will error when an rvalue is passed to aref readonly
parameter. Bothref
andin
will be usable at the callsite, but use ofref
will warn, like it will forin
parameters.
Conclusion
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.
Inconsistencies around accessibility checks for interface implementations
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.
Conclusion
No action today. We will go back to the drawing board and revisit.