【问题标题】:What is the origin of CS0060:The direct base class of a class type must be at least as accessible as the class type itselfCS0060的由来:类类型的直接基类必须至少和类类型本身一样可访问
【发布时间】:2013-12-31 14:43:26
【问题描述】:

我刚刚在 .net 中遇到了这个关于继承的基本规则:
CS0060:类类型的直接基类必须至少与类类型本身一样可访问

我很好奇为什么要制定这条规则。

有谁知道为什么首选这种继承? 有没有不同的语言。


    // CS0060.cs
class MyClass
// try the following line instead
// public class MyClass
{
}

public class MyClass2 : MyClass   // CS0060
{
   public static void Main()
   {
   }
}

谢谢

【问题讨论】:

  • 我知道但我的问题是为什么“类类型的基类必须至少与类类型本身一样可访问”?为什么会有这个限制
  • Inconsistent Accessability: Base Class is less accessible than class 的副本。你在MyClass之前省略了public,所以是internal,和MyClass2public冲突。
  • 这是意料之中的......你不会期望私有类的受保护/公共字段可以通过派生类在外部访问......你会吗??
  • 请学习use Google。第二个结果在此处完全显示了您的情况,并明确说明了您收到错误的原因。
  • @CodeCaster:从上下文看“为什么”的意思很清楚:各种因素导致设计团队做出这个决定;这些因素是什么?您的评论只是重申了规则,而没有解释规则的优点。 C# 本来可以设计为像 C++ 那样具有私有继承,但事实并非如此,这是有原因的。这个问题不适合 StackOverflow,不是因为它含糊不清,而是因为它不是关于实际代码的具体技术问题。相反,它是关于那天没有参加设计会议的任何人都不知道的历史。

标签: c# .net language-specifications


【解决方案1】:

我很好奇为什么要制定这条规则。有谁知道为什么首选这种继承?有没有不同的语言?

第二个问题比第一个问题更容易回答。是的,其他语言的做法不同。特别是,C++ 允许“private inheritance”;即继承关系成为类的私有实现细节。如果 C# 具有私有继承,那么显然基类可能比派生类更难访问。但是 C# 没有私有继承。

第一个问题很难回答,因为“为什么”问题本质上不适合 Stack Overflow。 “为什么要制定这条规则”的唯一正确答案?是“因为语言设计委员会认为,在考虑到许多相互竞争的设计目标时,这是最好的折衷方案”。

这可能不是一个令人满意的答案。要正确回答这个问题,不仅要列出所有这些设计目标及其相对优点,还要描述设计团队每个成员在做出决定时的心理状态,以及描述各种冲突的过程。出现的问题得到了解决。这个决定是十三年前做出的,所以这条路确实很冷。

十三年前的那一天我不在那个房间,但我可以告诉你设计委员会在决定是否允许私有继承时会考虑的因素:

  • 对“概念计数”的影响。 (用户必须了解多少相关概念才能正确使用该功能?该功能为语言添加了多少新概念?)
  • 该功能与 C++ 的相似之处或不同之处,这可能是有帮助的,也可能是令人困惑的。
  • C++ 中的功能成功。人们在 C++ 中使用它吗?他们正确使用它吗?是否每个 C++ 用户都足够了解此功能以做出正确的选择?
  • 与其他语言功能的交互量。这样的功能会以潜在的微妙或令人困惑的方式改变名称查找和重载解析。
  • 与相关语言功能的一致性级别。 (允许接口不那么容易访问。)
  • 实施困难。
  • 还有更多因素。

由于我没有三四个小时的空闲时间,我需要为此功能写下所有这些因素的详细分析,然后尝试追溯性地对设计团队进行心理分析,我认为你是将不得不忍受你的好奇心没有得到满足。

我建议以后不要在 StackOverflow 上问这样的问题。尽量坚持具体技术问题关于实际代码准确答案。

【讨论】:

  • 首先对不起我的语言不好。第二个谢谢你的回答。
  • @mohammedsameeh:你的英语很好!对于这个网站来说,这不是一个好问题。不客气。
【解决方案2】:
class BaseClass {...}
public class MyClass: BaseClass {...} // Error

http://msdn.microsoft.com/en-us/library/cx03xt0t.aspx

这是在 C# 语言规范中提到的,这也很有意义,因为在您的情况下,公共类可以在具有公共可访问性级别的“公共”上下文中使用,允许访问作为您的基类的非公共类这将是错误的行为。

根据 C# 语言规范 5.0:

(从http://www.microsoft.com/en-us/download/details.aspx?id=7029下载规范)

存在以下可访问性限制:

类类型的直接基类必须至少与类类型本身一样可访问

• 接口类型的显式基接口必须至少与接口类型本身一样可访问。

• 委托类型的返回类型和参数类型必须至少与委托类型本身一样可访问。

• 常量的类型必须至少与常量本身一样可访问。

• 字段的类型必须至少与字段本身一样易于访问。

• 方法的返回类型和参数类型必须至少与方法本身一样可访问。

• 属性的类型必须至少与属性本身一样可访问。

• 事件的类型必须至少与事件本身一样易于访问。

• 索引器的类型和参数类型必须至少与索引器本身一样可访问。

• 运算符的返回类型和参数类型必须至少与运算符本身一样可访问。

• 实例构造函数的参数类型必须至少与实例构造函数本身一样可访问。

【讨论】:

    【解决方案3】:

    所有后续类必须至少具有与您示例中的 MyClass2 相同的可访问性。

    这是合乎逻辑的,因此有以下示例。

    当你有一个内部类 A 和一个名为 Prop 的公共属性时。如果基类也不是公共的,你认为外部世界会如何知道你的派生公共类 B 有一个属性 Prop?

    【讨论】:

    • 这个答案的第一句话是错误的。界面不必具有相同的可访问性。
    【解决方案4】:

    我明白你的意思,@mohammed sameeh。这有什么价值?或者,如果 .net 的行为有所不同,如果它试图允许这样做,会有什么副作用?

    @Anirudh 在谈到该基类的安全性时谈到了这一点。

    如果您没有此限制,则始终隐藏“私人”/“内部”事物的安全模型可能会被破坏 - 否则会非常混乱!
    这确实是最大的潜在副作用,错误地暴露了属性和方法。

    既然子类根据定义继承了父类的属性和方法,在这种情况下应该如何考虑?
    .net 没有(甚至更多)关于如何在继承和子类中公开属性和方法的规则,而是通过维护和强制执行公开层次结构来简化事情。

    对于没有限制的类型转换等会发生什么,其他人可能有一个很酷的观点。

    当然也可能存在其他规则。看到另一种不同的语言可能会很有趣。

    但我们肯定需要某种规则,所以当其他人使用你的类或程序集时,你知道会发生什么。

    【讨论】:

    • C++ 的做法有所不同,根据 Eric Lipperts 的回答。
    【解决方案5】:
    class MyClass
    
    {
    }
    
    public class MyClass2 : MyClass   // CS0060
    {
       public static void Main()
       {
       }
    }
    

    这个错误的原因是因为 MyClass 不是公开的,所以你需要把它公开,只需在 class MyClass 之前添加 public

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      相关资源
      最近更新 更多