【问题标题】:Why is a property hiding Inherited function with same name?为什么属性隐藏具有相同名称的继承函数?
【发布时间】:2013-08-01 22:34:36
【问题描述】:

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

我认为这应该没问题,因为:

  1. property will compile 到 get_myName()(因此不会与 Foo::myName(int,int) 发生冲突)
  2. Foo::myName 有参数,而显然该属性没有(同样,没有冲突)。

但我仍然收到警告:

'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 的所有重载?

【问题讨论】:

  • 我能问一下为什么你的方法名和属性名一样吗?通常,如果返回类型涉及任何逻辑,则最好使用方法,否则属性
  • @Sayse 父类更通用,它需要参数来决定结果是什么。派生类更加具体,并且参数是固定的。该属性所做的只是 get{base.myName(this.a, this.b);}。所以你可以看到功能是一样的。该属性只是为了更容易编码。

标签: c# .net inheritance properties


【解决方案1】:

C# 规范的第 10.3.3 节包含:

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

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

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

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

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

10.3.9.1 节中提到了不能声明名为 get_myName 的方法这一事实,如 cmets 中所述。

【讨论】:

  • 规范地址get_myName在“10.3.9.1为属性保留的成员名称:对于类型T的属性P(§10.7),保留以下签名:T get_P();void set_P(T value);两者签名被保留,即使该属性是只读或只写。"
【解决方案2】:

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

class Program
{
    static void Main(string[] args)
    {

        Console.ReadLine();
    }

    void DoStuff(int i,int j)
    {

    }

    int DoStuff { get { return 10; } }
}

生产:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 2011-07-19
    相关资源
    最近更新 更多