简体   繁体   中英

Why is it valid to pass static types in and out of interface methods in C#?

I noticed that the following code seems to compile just fine, when I would've expected multiple errors:

public interface ITest
{
    Math Foo(MathF x, ref Console y);
}

Math, MathF, and Console are all static classes - is there any reason why this is valid, or is it just an oddity of the specification/compiler? When attempting to implement the interface, you then receive an error (I guess that means you can make an interface that's impossible to implement, which is kinda cool)

What's more, I can go one worse:

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
            }
        }
    }
}

Output:

Hello World!

Tested in VS 2022, using both C# 8.0 + .NET Core 3.1, and 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?

Questions like this can be difficult to answer. The strict literal answer is because that's how C#'s grammar is defined.

Quoting from 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 ).

From there you'll have to knock yourself out with this: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#146-methods


But of course that's not really an enlightening answer. I think what you really want to know is "what is the wisdom in allowing insanity like this?". Which of course is an opinion-based question. So I'll answer that with these opinions of mine:

  • It would probably just make the language or its implementation more complex to prevent it at this level
  • It's already prevented at another level—it's impossible to implement that interface as you pointed out, so already nobody is able to write useful code like that
  • Why not allow it when there's already so much other insanity out there?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM