不一致的可访问性:基类比类不易访问

use*_*490 6 c# inheritance

我有下面的代码,我正在尝试做一些继承练习,但是当我尝试运行这段代码时,它给了我一个错误:

Inconsistent Accessability: Base Class is less accessible than class
Run Code Online (Sandbox Code Playgroud)

代码:

class Program
{
    static void Main()
    {

        FoodProducts Test = new FoodProducts();

        Test.Limit();



    }
}

public class FoodProducts : Products
{
    public void FoodProduct()
    {
        Console.WriteLine("This is food product");
    }

    public void Limit()
    {
        Console.WriteLine("This is an Attribute of a Product");
    }

}
Run Code Online (Sandbox Code Playgroud)

有人能帮助我吗?

Jon*_*art 14

错误是什么行,具体的错误文本是什么?另外,定义在Products哪里?

您可能正在获得CS0060:"不一致的可访问性:基类'class1'比类'class2'更难访问"因此,我假设您的Products类未标记为public.

当基类被标记为public(internal例如)之外的其他内容时会发生此问题,但是您尝试创建public派生类.

  • 很高兴解释为什么不允许这样做,即从隐藏的基类继承的公共类有什么问题. (5认同)

Ben*_*jol 10

仅仅为了像我这样厚厚的人的未来参考,我在以下情况下得到了这个并且无法弄清楚出了什么问题:

public class Foo : Base<Bar> {} <-- Inconsistent accessibility

public class Base<T> {}
Run Code Online (Sandbox Code Playgroud)

我花了一段时间才弄清楚罪魁祸首在这里:

internal class Bar {}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你——这让我节省了半天的时间,不用再把头撞在桌子上了。我不会考虑查看“T”类的可访问性。 (2认同)
  • 你是救星 (2认同)

Can*_*ide 6

可能该课程Products不是公开的。添加publicProducts类定义中。

如果你有类似的东西:

class Products {
 ...
}
Run Code Online (Sandbox Code Playgroud)

C# 编译器将Products类解释为内部类。


Ray*_*Luo 6

这里有很多答案建议也将您的基类也改为公开。从某种意义上说它们是正确的,但是它们错过了一个同样有效的选择,那就是将您的派生类更改为内部类(以匹配基类的可访问性)。

因此,真正的答案(到目前为止)是让您的基类和派生类具有相同的可访问性。

对于那些想知道为什么的人,长答案是:当公共派生类尝试继承内部或私有基类时,子类是否也想公开那些公共类将在语义上变得不清楚(稍后会详细介绍)。内部/私有基类中的方法。埃里克·利珀特(Eric Lippert)在他的博客文章中做了详细的解释:为什么从内部阶级派生公共阶级是非法的?,在下面引用(略有修改):

一方面,它是基类的公共方法,因此似乎应该可以访问(派生类也可以访问)。另一方面,Base是内部的这一事实证明了它的内部方法应该在程序集外部不可访问。C#的基本设计原则是,当意图不明确时,编译器会通过失败使您注意到这一事实。

PS:话虽这么说,但有人可能会争辩说,编译器可能只坚持“两只手中的一只”,而且仍然具有确定性。那么,为什么没有以一种特定的方式来选择设计决策呢?对于这样的后续问题,答案是,这都归结为以下设计哲学(同样,引自Eric的博客文章):

这种语言规则鼓励您使用继承关系来建模业务域语义,而不是将其用作代码重用的机制。

这就是C#已经做出的选择。

最后,出于完整性的考虑,值得一提的是,以上的设计哲学不一定是使用继承的通用且唯一的方法。(哎呀,其他一些语言甚至根本没有公共/内部概念,它们仍然很成功)。就个人而言,如果我们也想使用继承机制进行代码重用,我认为没有错。但是C#已经选择仅将继承用于业务域语义。就是这样。

  • 我没有遵循这个逻辑......我不明白为什么意图不清楚,它可能与继承即代码重用无关。很简单:public-internal 方法应该在内部是公开的,并且在外部是不可访问的,就像在所有其他情况下一样。_一方面,它是基类的公共方法,因此它似乎应该是可访问的_ - 当基类是内部的时没有意义。 (2认同)