考虑以下代码:
interface I {
string M1() => "I.M1";
string M2() => "I.M2";
}
abstract class A : I {}
class C : A {
public string M1() => "C.M1";
public virtual string M2() => "C.M2";
}
class Program {
static void Main() {
I obj = new C();
System.Console.WriteLine(obj.M1());
System.Console.WriteLine(obj.M2());
}
}
Run Code Online (Sandbox Code Playgroud)
它在 .NET Core 3.1.402 中产生以下意外输出:
I.M1
C.M2
Run Code Online (Sandbox Code Playgroud)
类A
没有 的成员的隐式或显式实现I
,所以我希望默认实现用于C
,因为C
继承了 的接口映射A
并且没有显式地重新实现I
。根据 ECMA-334 (18.6.6) 和 C# 6.0 语言规范: …
我的问题是由Eric Lippert的博客文章推动的.请考虑以下代码:
using System;
class Program {
class A {}
class B {}
static void M(A x, B y) { Console.WriteLine("M(A, B)"); }
static void Call(Action<A> f) { f(new A()); }
static void Call(Action<B> f) { f(new B()); }
static void Main() { Call(x => Call(y => M(x, y))); }
}
Run Code Online (Sandbox Code Playgroud)
这种成功并打印编译M(A, B)
,因为编译器计算出该类型的x
和y
在lambda表达式应该是A
和B
分别.现在,添加一个重载Program.M
:
using System;
class Program {
class A {}
class B {}
static void …
Run Code Online (Sandbox Code Playgroud) 为什么以下代码在 C# 11 中无法编译?
// Example 1 - fails
class C {
public Span<int> M(ref int arg) {
Span<int> span;
span = new Span<int>(ref arg);
return span;
}
}
Run Code Online (Sandbox Code Playgroud)
它产生两个编译错误:
错误CS9077:无法通过 ref 参数通过引用“arg”返回参数;它只能在 return 语句中返回。
错误 CS8347:无法在此上下文中使用“Span.Span(ref int)”的结果,因为它可能会在其声明范围之外公开参数“reference”引用的变量。
它们对我来说都没有意义:我的代码不会尝试arg
通过 ref 参数返回,并且它不能公开arg
其声明范围之外引用的变量。
对比之下,下面两段代码编译成功:
// Example 2 - succeeds
class C {
public Span<int> M(ref int arg) {
Span<int> span = new Span<int>(ref arg);
return span;
}
}
Run Code Online (Sandbox Code Playgroud)
// Example 3 - succeeds
class C {
public Span<int> …
Run Code Online (Sandbox Code Playgroud)