为什么我的静态方法隐藏了我的实例方法?

isn*_*ntn 6 .net c#

以下代码是否应该发出警告?

class Foo { public void Do() { /*...*/ } /*...*/ }
class Bar : Foo { public static void Do()  { /*...*/ } /*...*/ }
Run Code Online (Sandbox Code Playgroud)

它给:

"警告CS0108:'Bar.Do()'隐藏继承的成员'Foo.Do()'.如果想要隐藏,请使用new关键字."

如果我对代码进行了更改:

class Foo { public static void Do() { /*...*/ } /*...*/ }
class Bar : Foo { public void Do()  { /*...*/ } /*...*/ }
Run Code Online (Sandbox Code Playgroud)

我得到同样的警告.

但是,如果我做出以下更改,警告就会消失.

class Foo { public void Do() { /*...*/ } /*...*/ }
class Bar : Foo { new public static void Do() { /*...*/ } /*...*/ }
Run Code Online (Sandbox Code Playgroud)

让我做进一步的改变:

class Foo { public void Do() { /*...*/ } /*...*/ }
class Bar : Foo { 
    new public static void Do() 
    { new Bar().Do();/*...*/ } /*...*/ 
}
Run Code Online (Sandbox Code Playgroud)

这不编译:

"错误CS0176:无法使用实例引用访问成员'Bar.Do()';而是使用类型名称限定它."

所以,我通过静态方法的实例引用失去了对继承方法的访问权限!

它背后的逻辑是什么?或者我在某个地方打错了?

当我试图为从'Form'派生的表单定义一个静态方法'Show'时,我遇到了这个问题.

Jon*_*eet 5

你认为这个bug在哪里?有警告的事实是绝对正确的.从C#3.0规范,第10.3.4节:

允许类成员声明声明与继承成员具有相同名称或签名的成员.发生这种情况时,称派生类成员隐藏基类成员.隐藏继承的成员不会被视为错误,但它确实会导致编译器发出警告.为了抑制警告,派生类成员的声明可以包含一个new修饰符,以指示派生成员是否要隐藏基本成员.

您的方法调用失败的事实是更微妙的,但它基本上是因为成员查找算法选择静态方法,然后使用7.5.5.1节的这一部分:

执行所选最佳方法的最终验证:

该方法在方法组的上下文中进行验证:如果最佳方法是静态方法,则方法组必须由简单名称或成员访问类型生成.如果最佳方法是实例方法,则方法组必须由简单名称,通过变量或值的成员访问或基本访问产生.如果这些要求都不成立,则会发生编译时错误.