不一致的可访问性:基类的可访问性低于子类
本文关键字:访问 子类 基类 不一致 于子类 | 更新日期: 2023-09-27 18:14:20
我正在阅读Joseph Albabari和Ben Albabari合著的《c# 4.0简介》一书。从那里我发现了访问修饰符的主题限制。第91页,主题"访问修饰符的限制"
引自书中。
编译器防止任何不一致的访问修饰符的使用。为例如,子类本身可能比基类更难访问,但不能更多
这就是说基类应该和子类一样或更容易访问。因此,如果基类是内部的,那么子类应该是私有或内部的。如果基类是私有的,而子类是公共的,则会生成编译时错误。当我在Visual Studio中尝试这个时,我发现了一些奇怪的行为。
尝试1:基是私有的,子类是私有的(工作,正确的行为)这也适用于如果两者都是内部的,公共的
private class A { }
private class B : A { } // Works
尝试2:基类是私有的,子类是公共的或内部的(这失败了,正确的行为)
private class A { }
public class B : A { } // Error
Try 3: Base是internal and sub是public(这是有效的,但它应该失败。As基类比子类
更难访问internal class A { }
public class B : A { } // Works, but why
现在我的问题是为什么尝试3没有失败?子类是公共的,比基类更容易访问,基类是内部的。就连书里都说这应该失败。但是Visual Studio成功地编译了它。这应该起作用吗?
编辑:我在vs中创建了一个新的控制台项目。在Program.cs中我添加了我的代码。这里是Program.cs文件的完整代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication
{
class Program
{
internal class A { }
public class B : A { } // Error
static void Main()
{
}
}
}
您正在将您的嵌套类放置在另一个internal
类中。
例如:
class Program
{
static void Main(string[] args)
{
}
internal class A { }
public class B : A { }
}
它将编译,因为包装类的internal
修饰符使B
类上的public
修饰符无效。相反,类型B
的可访问性受到其包装类Program
的限制——它的可访问域也是internal
。
如果您将其更新为:
class Program
{
static void Main(string[] args)
{
}
}
internal class A { }
public class B : A { }
将抛出不一致可见性编译器错误。或者,如果您将Program
重新定义为public
而不是internal
,它也会抛出错误。在这种情况下,B
的可访问域现在是public
,不再受Program
的internal
可访问域的限制。
来自c#规范3.5.2 Accessibility Domains:
在类型T中声明的嵌套成员M的可访问域在一个程序中,P的定义如下(注意M本身可以可能是一个类型):
如果M声明的可访问性是公共的,则M的可访问域是t的可访问域。
和MSDN对无障碍域的描述:
如果成员嵌套在另一个类型中,则其可访问域由成员的可访问性级别和直接包含类型的可访问性域。
如果包装类型Program
为internal
,则嵌套类型B
为public
将具有匹配Program
的可访问性,因此它被视为internal
,并且不会抛出编译器错误。
私有继承类不能在其他类中访问,当你与其他公共类继承私有类时,它包含了私有类的引用和它的数据,所以这是不可能的。
abstract class test
{
public abstract void add();
public int num1;
public string str;
}
class test3 : test1
{
public override void add()
{
throw new NotImplementedException();
}
}
两个类都是私有的。如果使用internal,则只能在汇编中访问。