-1

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

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

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


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

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

谢谢

4

5 回答 5

5

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

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

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

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

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

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

由于我没有三四个小时的空闲时间来为这个特性写一份关于所有这些因素的详细分析,然后尝试追溯性地对设计团队进行心理分析,我想你会有带着未满足的好奇心生活。

我建议以后不要在 StackOverflow 上问这样的问题。尝试坚持有关具有精确答案的实际代码的特定技术问题。

于 2013-12-31T16:01:02.310 回答
3
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下载规范)

存在以下可访问性约束:

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

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

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

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

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

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

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

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

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

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

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

于 2013-12-31T14:48:37.053 回答
1

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

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

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

于 2013-12-31T14:51:47.727 回答
0

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

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

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

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

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

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

但可以肯定的是,我们需要某种规则,因此当其他人使用您的课程或程序集时,您知道会发生什么。

于 2013-12-31T15:14:47.920 回答
0
class MyClass

{
}

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

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

于 2021-03-17T14:15:35.187 回答