C# CS0060的起源是什么:类类型的直接基类必须至少与类类型本身一样可访问
我刚刚在.net中遇到了关于继承的基本规则:C# CS0060的起源是什么:类类型的直接基类必须至少与类类型本身一样可访问,c#,.net,language-specifications,C#,.net,Language Specifications,我刚刚在.net中遇到了关于继承的基本规则: CS0060:类类型的直接基类必须至少与类类型本身一样可访问 我很好奇为什么要制定这个规则 有人知道为什么这种继承方式更受欢迎吗? 有没有不同的语言可以做到这一点 谢谢 C#语言规范中提到了这一点,这也是非常有意义的,因为在您的情况下,公共类可以在“公共”上下文中使用,公共可访问性级别允许访问作为基类的非公共类,这将是错误的行为 根据C语言规范5.0: (从下载规范) 存在以下可访问性约束: •类类型的直接基类必须至少与类类型本身一样可访问 •接
CS0060:类类型的直接基类必须至少与类类型本身一样可访问 我很好奇为什么要制定这个规则 有人知道为什么这种继承方式更受欢迎吗? 有没有不同的语言可以做到这一点
谢谢 C#语言规范中提到了这一点,这也是非常有意义的,因为在您的情况下,公共类可以在“公共”上下文中使用,公共可访问性级别允许访问作为基类的非公共类,这将是错误的行为 根据C语言规范5.0: (从下载规范) 存在以下可访问性约束: •类类型的直接基类必须至少与类类型本身一样可访问 •接口类型的显式基本接口必须至少与接口类型本身一样可访问 •委托类型的返回类型和参数类型必须至少与委托类型本身一样可访问 •常数的类型必须至少与常数本身一样容易访问 •字段类型必须至少与字段本身一样可访问 •方法的返回类型和参数类型必须至少与方法本身一样可访问 •财产的类型必须至少与财产本身一样容易接近 •事件类型必须至少与事件本身一样可访问 •索引器的类型和参数类型必须至少与索引器本身一样可访问 •操作员的返回类型和参数类型必须至少与操作员本身一样可访问
•实例构造函数的参数类型必须至少与实例构造函数本身具有相同的可访问性。所有后续类必须至少与示例中的MyClass2具有相同的可访问性 这是合乎逻辑的,因此下面的例子
当您有一个名为Prop的公共属性的内部类a时。如果基类也不是公共的,你认为外部世界如何知道派生的公共类B有属性属性属性?我明白你的意思,@mohammed sameeh。这有什么价值?或者,如果.net尝试允许这样做,那么如果.net表现不同,会有什么副作用 @当阿尼鲁德谈到那个基础阶级的安全性时,他正谈到这一点 如果您没有这个限制,那么始终隐藏“私有”/“内部”内容的安全模型可能会被打破——或者非常混乱
这确实是最大的潜在副作用,错误地暴露属性和方法 根据定义,由于子类继承父类的属性和方法,因此在这种情况下应如何考虑它们?
net没有(甚至更多)关于如何在继承和子类化中公开属性和方法的规则,而是通过维护公开层次结构并强制执行它来简化事情 其他人可能有一个很酷的观点来说明在没有限制的情况下,类型转换或类似的东西会发生什么 当然,也可能存在其他规则。看到另一种语言以不同的方式表达可能会很有趣 但是可以肯定的是,我们需要某种规则,所以当其他人使用您的类或程序集时,您知道会发生什么 我很好奇为什么要制定这个规则。有人知道为什么这种继承方式更受欢迎吗?有没有不同的语言 第二个问题比第一个问题更容易回答。是的,其他语言做的不同。特别是C++允许“也就是说,继承关系成为类的私有实现细节。如果C#具有私有继承,那么基类显然比派生类更难访问。但C#没有私人继承权 第一个问题很难回答,因为“为什么”问题本质上不适合堆栈溢出。“为什么要制定这条规则?”的唯一正确答案是“因为语言设计委员会认为,在考虑到许多相互竞争的设计目标时,这是最好的折衷方案” 这可能不是一个令人满意的答案。要正确回答这个问题,不仅需要列出所有这些设计目标及其相对优点,还需要描述设计团队每个成员在做出决策时的心理状态,以及描述通过什么过程解决了产生的各种冲突。这个决定是在十三年前做出的,所以这条小路确实很冷 13年前的那一天我不在那个房间,但我可以告诉你一些设计委员会在决定是否允许私人继承时会考虑的因素:
- 对“概念计数”的影响。(为了正确使用该功能,用户必须理解多少相关概念?该功能为语言添加了多少新概念?)
- 与其他语言功能的交互量。这种特性可能会以微妙或令人困惑的方式改变名称查找和重载解析
- 与相关语言功能的一致性级别。(允许较少访问接口。)
- 实施难度
// CS0060.cs class MyClass // try the following line instead // public class MyClass { } public class MyClass2 : MyClass // CS0060 { public static void Main() { } }
class BaseClass {...} public class MyClass: BaseClass {...} // Error
class MyClass { } public class MyClass2 : MyClass // CS0060 { public static void Main() { } }