Add LDM notes for Feb. 25th, 2019
This commit is contained in:
parent
afe6679f71
commit
b83a527fbc
88
meetings/2019/LDM-2019-02-25.md
Normal file
88
meetings/2019/LDM-2019-02-25.md
Normal file
|
@ -0,0 +1,88 @@
|
|||
|
||||
# C# Language Design Notes for Feb 25th, 2019
|
||||
|
||||
## Agenda
|
||||
|
||||
Semantics of `base()` calls in default interface implementations and classes
|
||||
|
||||
## Discussion
|
||||
|
||||
The exact semantics of `base()` are still unresolved. Consider
|
||||
the following legacy `base` call.
|
||||
|
||||
```C#
|
||||
class A
|
||||
{
|
||||
virtual void M() {}
|
||||
}
|
||||
|
||||
class B : A
|
||||
{
|
||||
// override void M() { }
|
||||
}
|
||||
|
||||
class C : B
|
||||
{
|
||||
override void M() => base.M();
|
||||
}
|
||||
```
|
||||
|
||||
The behavior for `base` is to find the "nearest" implementation and call
|
||||
that implementation using a direct call, meaning if B.M is uncommented it
|
||||
will be called, while if it commented out then A.M will be called. Notably,
|
||||
if `B` is uncommented at compile time, but at runtime the `B.M` override is
|
||||
not present *the runtime will call A.M.* This is because the runtime will
|
||||
continue looking through base classes for a matching signature if the target
|
||||
method is not present.
|
||||
|
||||
Most importantly, the runtime *does not* yet have this behavior for `base()`
|
||||
calls in interface implementations. This is because there could be multiple
|
||||
paths to search down and the current IL encoding does not provide a root
|
||||
definition to search towards.
|
||||
|
||||
For example,
|
||||
|
||||
```C#
|
||||
interface IA
|
||||
{
|
||||
void M();
|
||||
}
|
||||
interface IB : IA
|
||||
{
|
||||
void IA.M() // If this gets removed, the IC.M call will fail
|
||||
{
|
||||
base(IA).M();
|
||||
}
|
||||
}
|
||||
interface IC : IB
|
||||
{
|
||||
void IA.M() => base(IB).M();
|
||||
}
|
||||
```
|
||||
|
||||
At the moment, we do not have the time to implement an entire new IL form
|
||||
for `base()` calls, so we have to implement a behavior in absence of that
|
||||
feature.
|
||||
|
||||
Choices:
|
||||
|
||||
1. No `base()` call
|
||||
2. `base()` call can only target the original definition of the method
|
||||
3. `base(T).M()` call is a direct call to `T` and an error if the method
|
||||
doesn't exist
|
||||
4. `base(T)` starts searching in `T`, but in the compiler looks at the bases
|
||||
for a unique, most derived implementation.
|
||||
|
||||
For feature evolution, we then have three more choices later.
|
||||
|
||||
1. Stay as-is
|
||||
2. New opcode/behavior for `base()`
|
||||
3. New opcode/behavior for `base.` and `base()`
|
||||
|
||||
**Conclusion**
|
||||
|
||||
For the first choice, let's do (3). The emitted code will be a direct call to
|
||||
that method. It is expected that the runtime will throw an exception if an
|
||||
implementation is not present in that type. For binding, in classes the
|
||||
signature used will be the closest override, while for interfaces the
|
||||
signature will be the member definition.
|
|
@ -40,16 +40,18 @@
|
|||
- Triage [#2152](https://github.com/dotnet/csharplang/issues/2152): "Allow Obsolete attribute on getters and setters"
|
||||
- Open issues in recursive pattern-matching https://github.com/dotnet/csharplang/issues/2095
|
||||
|
||||
# C# Language Design Notes for 2019
|
||||
|
||||
Overview of meetings and agendas for 2019
|
||||
|
||||
## Feb 25, 2019
|
||||
|
||||
[C# Language Design Notes for Feb 20, 2019](LDM-2019-02-25.md)
|
||||
|
||||
- Open issues in default interface methods (https://github.com/dotnet/csharplang/issues/406).
|
||||
- Base calls
|
||||
- We currently have open issues around `protected`, `internal`, reabstraction, and `static` fields among others.
|
||||
|
||||
# C# Language Design Notes for 2019
|
||||
|
||||
Overview of meetings and agendas for 2019
|
||||
|
||||
## Feb 20, 2019
|
||||
|
||||
[C# Language Design Notes for Feb 20, 2019](LDM-2019-02-20.md)
|
||||
|
|
Loading…
Reference in a new issue