以下代码是否应该发出警告?
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'时,我遇到了这个问题.
你认为这个bug在哪里?有警告的事实是绝对正确的.从C#3.0规范,第10.3.4节:
允许类成员声明声明与继承成员具有相同名称或签名的成员.发生这种情况时,称派生类成员隐藏基类成员.隐藏继承的成员不会被视为错误,但它确实会导致编译器发出警告.为了抑制警告,派生类成员的声明可以包含一个new修饰符,以指示派生成员是否要隐藏基本成员.
您的方法调用失败的事实是更微妙的,但它基本上是因为成员查找算法选择静态方法,然后使用7.5.5.1节的这一部分:
执行所选最佳方法的最终验证:
该方法在方法组的上下文中进行验证:如果最佳方法是静态方法,则方法组必须由简单名称或成员访问类型生成.如果最佳方法是实例方法,则方法组必须由简单名称,通过变量或值的成员访问或基本访问产生.如果这些要求都不成立,则会发生编译时错误.
| 归档时间: |
|
| 查看次数: |
1263 次 |
| 最近记录: |