为什么在 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 问题。所以我会用我的这些观点来回答这个问题:

  • 在这个级别阻止它可能只会使语言或其实现更加复杂
  • 它已经在另一个层面上被阻止了——不可能像你指出的那样实现那个接口,所以已经没有人能够像那样编写有用的代码
  • 既然已经有这么多其他的疯狂行为,为什么不允许它呢?