为什么在 C# 中将静态类型传入和传出接口方法是有效的?
Why is it valid to pass static types in and out of interface methods in C#?
我注意到以下代码似乎编译得很好,而我预计会出现多个错误:
public interface ITest
{
Math Foo(MathF x, ref Console y);
}
Math、MathF 和 Console 都是静态的 类 - 有什么理由证明这是有效的,还是只是 specification/compiler 的一个奇怪之处?当尝试实现接口时,你会收到一个错误(我想这意味着你可以创建一个无法实现的接口,这有点酷)
更重要的是,我可以更糟:
using System;
namespace StaticParams
{
internal class Program
{
static void Main(string[] args)
{
ITest.Bar(null);
}
public interface ITest
{
Math Foo(MathF x, ref Console y);
static void Bar(Math x)
{
Baz(x);
}
static void Baz(Math x)
{
Console.WriteLine("Hello World" + x + "!"); // x is null so we can't do much with it
}
}
}
}
输出:
Hello World!
在 VS 2022 中测试,同时使用 C# 8.0 + .NET Core 3.1 和 C# 10.0 + .NET 6.0.4。
is there any reason why this is valid, or is it just an oddity of the specification/compiler?
像这样的问题可能很难回答。严格的字面答案是因为 C# 的语法就是这样定义的。
引用自
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/interfaces :
interface_declaration
: attributes? interface_modifier* 'partial'? 'interface'
identifier variant_type_parameter_list? interface_base?
type_parameter_constraints_clause* interface_body ';'?
;
interface_body
: '{' interface_member_declaration* '}'
;
interface_member_declaration
: interface_method_declaration
| interface_property_declaration
| interface_event_declaration
| interface_indexer_declaration
;
interface_method_declaration
: attributes? 'new'? return_type identifier type_parameter_list?
'(' formal_parameter_list? ')' type_parameter_constraints_clause* ';'
;
The attributes, return_type, identifier, and formal_parameter_list of an interface method declaration have the same meaning as those of a method declaration in a class (§14.6).
从那里你将不得不用这个来击倒自己:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#146-methods
但这当然不是一个真正有启发性的答案。我认为您真正想知道的是“允许这样的精神错乱有什么智慧?”。这当然是一个 opinion-based 问题。所以我会用我的这些观点来回答这个问题:
- 在这个级别阻止它可能只会使语言或其实现更加复杂
- 它已经在另一个层面上被阻止了——不可能像你指出的那样实现那个接口,所以已经没有人能够像那样编写有用的代码
- 既然已经有这么多其他的疯狂行为,为什么不允许它呢?
我注意到以下代码似乎编译得很好,而我预计会出现多个错误:
public interface ITest
{
Math Foo(MathF x, ref Console y);
}
Math、MathF 和 Console 都是静态的 类 - 有什么理由证明这是有效的,还是只是 specification/compiler 的一个奇怪之处?当尝试实现接口时,你会收到一个错误(我想这意味着你可以创建一个无法实现的接口,这有点酷)
更重要的是,我可以更糟:
using System;
namespace StaticParams
{
internal class Program
{
static void Main(string[] args)
{
ITest.Bar(null);
}
public interface ITest
{
Math Foo(MathF x, ref Console y);
static void Bar(Math x)
{
Baz(x);
}
static void Baz(Math x)
{
Console.WriteLine("Hello World" + x + "!"); // x is null so we can't do much with it
}
}
}
}
输出:
Hello World!
在 VS 2022 中测试,同时使用 C# 8.0 + .NET Core 3.1 和 C# 10.0 + .NET 6.0.4。
is there any reason why this is valid, or is it just an oddity of the specification/compiler?
像这样的问题可能很难回答。严格的字面答案是因为 C# 的语法就是这样定义的。
引用自 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/interfaces :
interface_declaration
: attributes? interface_modifier* 'partial'? 'interface'
identifier variant_type_parameter_list? interface_base?
type_parameter_constraints_clause* interface_body ';'?
;
interface_body
: '{' interface_member_declaration* '}'
;
interface_member_declaration
: interface_method_declaration
| interface_property_declaration
| interface_event_declaration
| interface_indexer_declaration
;
interface_method_declaration
: attributes? 'new'? return_type identifier type_parameter_list?
'(' formal_parameter_list? ')' type_parameter_constraints_clause* ';'
;
The attributes, return_type, identifier, and formal_parameter_list of an interface method declaration have the same meaning as those of a method declaration in a class (§14.6).
从那里你将不得不用这个来击倒自己: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#146-methods
但这当然不是一个真正有启发性的答案。我认为您真正想知道的是“允许这样的精神错乱有什么智慧?”。这当然是一个 opinion-based 问题。所以我会用我的这些观点来回答这个问题:
- 在这个级别阻止它可能只会使语言或其实现更加复杂
- 它已经在另一个层面上被阻止了——不可能像你指出的那样实现那个接口,所以已经没有人能够像那样编写有用的代码
- 既然已经有这么多其他的疯狂行为,为什么不允许它呢?