接口继承

时间:2009-01-17 12:12:20

标签: c# interface

如果我有一个界面:

interface IFoo
{
    int Offset {get;}
}
我能说到这个:

interface IBar: IFoo
{   
    int Offset {set;}
}

所以IBar的消费者能够设置或获得?

5 个答案:

答案 0 :(得分:7)

这很接近,但没有香蕉。

interface IFoo
{
    int Offset { get; }
}

interface IBar : IFoo
{
    new int Offset { set; }
}

class Thing : IBar
{
    public int Offset { get; set; }
}

请注意IBar中的new关键字,但这会覆盖IFoo的get访问器,因此IBar没有get。因此,没有你不能真正创建IBar,只需添加一个集合,同时保持现有的get。

答案 1 :(得分:7)

不,你不能!

(我即将写“是”,但在阅读了安东尼的帖子后,尝试了一些调整,我发现答案是否定的!)

class FooBar : IFoo, IBar
{
    public int Offset{get;set;}
}

(安东尼指出会产生警告,可以通过添加“新”关键字来修复。)

尝试代码时:

IBar a = new FooBar();
a.Offset = 2;
int b = a.Offset;

最后一行会产生编译错误,因为你隐藏了IBar的Offset setter。

编辑:修复了类中属性的accesibillity修饰符。 Thx Anthony!

答案 2 :(得分:3)

+1到Arjan Einbu

当然IBar的消费者将无法获得Offset属性的值,因为IFoo的继承不会改变IBar中定义的Offset属性的语义 - 编译器会因某种原因警告您。当您使用“new”关键字编译器时,完全消除消歧并将IBar.Offset视为只写。但是,从IBar接口继承的 class 的消费者将能够获取和设置Offset属性。

如果使用显式接口实现,差异会变得更明显:

class Boo: IBar
{
    int IFoo.Offset { get { return 0; } }
    int IBar.Offset 
    {
          set { }  // OK - IBar has a setter
          get { return 1; } // compiler error - IBar.Offset doesn't inherit setter

    }
}

class Program
{
    static void Main(string[] args)
    {
        Boo b = new Boo();
        int x = ((IFoo) b).Offset; // OK - IFoo.Offset has getter
        ((IBar) b).Offset = 1; // OK - IBar.Offset has setter
        x = ((IBar) b).Offset; // compiler error - IBar doesn't inherit 
                               // getter from IFoo
    }
}

答案 3 :(得分:2)

你可以做的是让IBar接口有吸气剂和定位器(没有必要没有这个)。当你在IBar中只有setter时,你真的明确地说“在IBar界面上Offset propery是只写的”,这显然不是你想要的。

interface IFoo 
{ 
    int Offset { get;}
}

interface IBar : IFoo 
{
    new int Offset { get; set; } 
}

class Thing : IBar 
{
    public int Offset
    {
        get;
        set;
    }
}

现在你可以像这样使用类Thing:

var t = new Thing();
t.Offset = 1;
int read = t.Offset;

答案 4 :(得分:0)

如果属性getter和setter是独立实体,那么定义属性setter并从定义属性getter的接口继承的接口将允许读写语义。不幸的是,无论出于何种原因,vb.net和C#都不允许这样做。相反,getter是只读属性,setter是只写属性。如果类型定义了只写属性但继承了只读属性,则vb.net和C#将只看到只写属性。如果接口继承了一个暴露只读属性的接口和一个暴露只写属性的接口,那么这两个属性都不能在接口上使用,因为vb.net和C#都不愿意使用属性正在存在的事实读取或写入以确定是使用只读还是只写属性。相反,两种语言都会声明该属性是“模棱两可的”。

如上所述,解决方案是拥有一个接口,该接口继承具有只读属性的接口并实现读写属性。这将隐藏其他只读属性,但如果实现读写属性以返回相同的数据,那应该不是问题。实际上,在C#中处理隐式接口实现的方式允许使用相同的代码实现读写和只读接口(vb,有点令人讨厌,需要'只读'属性与其分开编码'读写'属性)。