'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.
Solution 1:[1]
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?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Matt Thomas |