c#多接口继承不允许具有相同名称的公共访问修饰符

本文关键字:访问 继承 接口 不允许 | 更新日期: 2023-09-27 18:02:34

这让我很困惑。
假设有两个接口。

public interface a
{
    void foo();
}
public interface b
{
    void foo();
}

这两个接口都有一个函数foo,我有一个提供显式实现的类:

public class alpha : a, b
{
    // why can't I put an access modifier here?
    // How would you be able to hide this from a derived class
    void a.foo()
    {
        Console.WriteLine("a");
    }
   void b.foo()
    {
        Console.WriteLine("b");
    }
}

和从alpha

派生的Class
public class beta : alpha
{
}

如何使foo私有或受保护,因为alpha不允许显式实现的访问修饰符,什么可以阻止别人调用:

var be = new beta();
(be as b).foo();

编辑

为什么当我不显式地提供实现时,我可以提供访问修饰符?

public class alpha : a, b
{
   //why this compile? 
   public void foo()
    {
        Console.WriteLine("both");
    }
}

c#多接口继承不允许具有相同名称的公共访问修饰符

由于接口a是公共的,任何实现a的类必须使a的方法可以隐式(通过公共方法)或显式地公开访问。显式实现是"某种程度上"私有的,因为它们只能通过接口访问。

简而言之,没有办法完全"隐藏"foo -你的类实现了ab,所以这些方法必须通过某种方式使可以访问。

即使只有一个接口,

也是正确的——具有方法名称冲突的多个接口只会迫使您使实现显式。如果你有一个接口,foo要么必须是public,要么是显式的。

什么可以阻止某人打电话

没什么,这就是重点!

betab,因此您可以将其视为b。如果您选择将其强制转换为b并调用显式foo实现,您将获得b实现。

如其他答案所示,这些是语言的规则,必须遵守。

示例说明为什么需要在接口实现中显式指定public:

class Base
{
   protected void Foo() { } 
}
public interface IFoo
{
   void Foo();
}

Base显式地选择不向类的用户公开方法Foo(除了派生,也可以是private)。

现在,如果另一个类想从Base派生并同时实现IFoo。如果语言允许只选择实现而不考虑访问修饰符,这将意味着Base.Foo现在由派生向每个调用者公开:

class Derived : Base, IFoo 
{
    // hypothetical compiler allows to pick any matching `void Foo` 
    // including inherited `protected void Base.Foo()`
}

这显然违背了Base类隐藏Foo方法的意图-因此语言必须要求Foo成为public才能被视为接口的一部分。

作为结果,你结束了"可选的"访问修饰符在接口实现中,你只有一个选项-必须指定public

请注意,Derived有两个选项来处理Foo -显式实现和new的阴影:

class Derived : Base, IFoo
{
   new public void Foo() {}
}