为什么一个属性隐藏具有相同名称的Inherited函数

本文关键字:函数 Inherited 一个 隐藏 属性 为什么 | 更新日期: 2023-09-27 18:25:55

我有一个类Foo,其中有一个函数myName
bar继承自Foo,并具有也称为myName 的属性

我认为这应该是可以的,因为:

  1. 该属性将编译为get_myName()(因此不会与Foo::myName(int,int)发生冲突)
  2. Foo::myName有参数,而属性显然没有(同样,没有colsion)

然而,我仍然得到警告:

'Bar.myName' hides inherited member 'Foo.myName(int, int)'. Use the new keyword if hiding was intended.

示例代码:

public class Foo
{
    public int myName(int a, int b)
    {
        return 0;
    }
}
class Bar: Foo
{
    int a;
    int b;
    int myName
    {
        get
        {
            return a + b;
        }
    }
}

此外,如果我将函数添加到bar中:

int get_myName() 
{
    return a+b;
}

不出所料,我得到了一个关于先前声明的函数的错误
那么这里发生了什么?除了get_myName()之外,该属性是否不允许我使用myName的所有重载?

为什么一个属性隐藏具有相同名称的Inherited函数

C#规范第10.3.3节包含:

派生类可以通过声明具有相同名称或签名的新成员来隐藏继承的成员。

它没有说明这两个成员必须是同一类成员。请注意,即使一个是属性,一个是方法,但仍有可能混淆它们的情况:

  • 属性可以是委托类型,例如Action<int, int>,在这种情况下PropertyName(10, 10)是有效的
  • 在某些使用属性名称的地方,您可能正在尝试执行方法组转换,因此它们都是有效的

在同一类中,我们遇到了第10.3节的规则:

  • 常量、字段、属性、事件或类型的名称必须与在同一类中声明的所有其他成员的名称不同
  • 方法的名称必须与同一类中声明的所有其他非方法的名称不同。[…]

第10.3.9.1节中提到了不能声明名为get_myName的方法的事实,如注释中所述。

我们甚至不需要图片中的继承-属性和方法之间不能有"重载":

class Program
{
    static void Main(string[] args)
    {
        Console.ReadLine();
    }
    void DoStuff(int i,int j)
    {
    }
    int DoStuff { get { return 10; } }
}

产品:

错误CS0102:类型"ConsoleApplication4.Program"已包含"DoStuff"的定义