接口继承而不隐藏

时间:2010-07-29 16:54:07

标签: c#

如果我写课,那么一切都好

class C
{
    protected int _attr;
    int attr { get { return _attr; } }
}

class CWithSet : C
{
    int attr { set { _attr = value; } }
}

但是,如果我写接口

interface I
{
    int attr { get; }
}

interface IWithSet : I
{
    int attr { set; }
}

然后我有了交战:“'IWithSet.attr'隐藏了继承成员'I.attr'。如果想要隐藏,请使用new关键字。”

如何写,以免得到警告?

5 个答案:

答案 0 :(得分:6)

来自C#规范:接口的继承成员特别不是接口声明空间的一部分。因此,允许接口声明与继承成员具有相同名称或签名的成员。当发生这种情况时,派生的接口成员被称为隐藏基接口成员。隐藏继承的成员不会被视为错误,但它确实会导致编译器发出警告。要禁止警告,派生接口成员的声明必须包含new修饰符,以指示派生成员旨在隐藏基本成员。 (Interface members)正确的实现是:

interface IWithSet : I
{
    new int attr { get; set; }
}

答案 1 :(得分:3)

您可能想要考虑是否值得重新定义接口的语义。我的意思是,除了您定义为“I”的只读接口之外,只有一个单独的只写接口可能是有意义的。

以下是一个例子:

interface IReadOnly
{
    int Attr { get; }
}

interface IWriteOnly
{
    int Attr { set; }
}

interface I : IReadOnly, IWriteOnly
{
}

class CReadOnly : IReadOnly
{
    protected int _Attr;
    public int Attr
    {
        get { return _Attr; }
    }
}

class C : CReadOnly, I
{
    public int Attr
    {
        get { return base.Attr; }
        set { _Attr = value; }
    }
}

编辑:我将C.Attr属性的get部分更改为return base.Attr而不是return _Attr;,以便与原始问题中的代码示例更加一致。我也认为这更正确,因为你可能在CReadOnly.Attr中定义了更复杂的逻辑,你不想复制。

某些接口和类已从原始示例重命名。 “我”成为“IReadOnly”,“IWithSet”成为“我”。 “C”变为“CReadOnly”,“CWithSet”变为“C”。

这是为我编写的,没有任何警告。

编辑:这是为我编译的,没有关于接口成员的警告。我确实得到了关于隐藏CReadOnly类属性的C类'Attr属性的1个警告,但这应该是完全可以预料到的,因为隐藏/阴影是我的例子中发生的事情。一个奇怪的事情:我可以发誓我编译(并运行!)这段代码几次,并看到0警告。那时我很困惑,但是我放手了......但是现在我看到了正如我所期待的那样的警告。也许只是一个编译器故障。

答案 2 :(得分:1)

如果您想要具有相同名称的单独属性,请使用new。警告是不言自明的。

另一方面,你想要的似乎更像是:

#pragma warning disable CS0108

interface IWithSet : I
{
    int attr { get; set; }
}

#pragma warning restore CS0108

答案 3 :(得分:0)

可能不完美,但有一种解决办法可能是:

interface IWithSet : I
{
    void SetAttr(int value);
}

答案 4 :(得分:0)

如何:

interface IWithSet : I
{
    new int attr { get; set; }
}

缺点是IWithSet将始终同时具有getter和setter,即使删除了'I'中的getter:

interface I { }

如果你定义这两个接口假设'我'将永远有getter,那么这种方法没有任何问题,这将在一个用于限制访问的接口层次结构中正常工作,而不是封装特定于a的逻辑抽象层(类似于典型的读/写类型结构,其中作者继承了读者对读者具有读取权限的SAFE假设的所有读者访问权限。)。