为什么C#编译器的重载决议算法处理静态和实例成员具有相同的签名一样的吗?编译器、决议、静态、算法

2023-09-03 15:44:46 作者:她的名字贯穿我的一生

让我们有两个成员相等的签名,但一个是静态的,另一个 - 是不是:

 类Foo
{
    公共无效测试(){Console.WriteLine(实例); }

    公共静态无效测试(){Console.WriteLine(静态); }
}
 

但这样的code生成带来了一个编译器错误:

  

输入富已经定义了一个名为测试具有相同的参数类型的成员

但是,为什么?

vs最小编译器 SnippetCompiler 绿色版下载

让我们编译的成功,则:

Foo.Test()应该输出静

新富()测试(); 应该输出实例

无法调用静态成员,而不是实例之一,因为在这种情况下,会出现另一种更合理的编译器错误:

  

的成员Foo.Test()不能用一个实例参考访问;与类型名称限定它,而不是

解决方案

怎么样,从一个实例方法:

 测试();
 

什么调用?你可能想给实例方法优先在静态方法,但都将适用。

我会说,即使它被允许,这将是一个根本的坏主意,从一个可读性点做到这一点...例如,如果你改变了一个方法,名为测试从静态的到实例,它会以一种微妙的方式改变的意思。

换句话说,我有这种被禁止的没有问题的:)

Let we have two members equal by signature, but one is static and another - is not:

class Foo
{
    public void Test() { Console.WriteLine("instance"); }

    public static void Test() { Console.WriteLine("static"); }
}

but such code generate brings a compiler error:

Type 'Foo' already defines a member called 'Test' with the same parameter types

But why?

Let we compiled that successfully, then:

Foo.Test() should output "static"

new Foo().Test();should output "instance"

Can't call the static member instead of instance one because in this case another, more reasonable compiler error will occur:

Member 'Foo.Test()' cannot be accessed with an instance reference; qualify it with a type name instead

解决方案

What about, from an instance method:

Test();

What would that call? You'd probably want to give the instance method "priority" over the static method, but both would be applicable.

I would say that even if it were allowed, it would be a fundamentally bad idea to do this from a readability point of view... for example, if you changed a method which called Test from being static to instance, it would change the meaning in a subtle way.

In other words, I have no problem with this being prohibited :)