8

我正在阅读 Joseph Albabari 和 Ben Albabari 所著的“C# 4.0 in a nutshell”一书。从那里我找到了关于访问修饰符的主题限制。第 91 页,主题“访问修饰符的限制”。

引自书中。

编译器防止任何不一致的访问修饰符使用。例如,子类本身可能比基类更难访问,但不会更多

所以这说明基类应该比子类更容易访问。因此,如果基类是内部的,那么子类应该是私有的或内部的。如果基类是私有的,子类是公有的,则会产生编译时错误。在 Visual Studio 中尝试此操作时,我发现了一些奇怪的行为。

尝试1:基类是私有的,子类是私有的(有效,正确的行为)如果两者都是内部的,公共的,这也有效。

private class A { }
private class B : A { }         // Works

尝试 2:基础是私有的,子类是公共的或内部的(这失败了,正确的行为)

private class A { }
public class B : A { }          // Error

尝试 3:Base 是内部的并且 sub 是公共的(这可行,但它应该失败。因为 Base 比子类更难访问

internal class A { }
public class B : A { }          // Works, but why

现在我的问题是为什么 Try 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()
        {
        }
    }
}
4

2 回答 2

12

您将嵌套类放在另一个internal类中。

例如,给定:

class Program
{
    static void Main(string[] args)
    {
    }

    internal class A { }
    public class B : A { }
}

它将编译,因为包装internal类的public修饰符使类上的修饰符B没有实际意义。相反, typeB的可访问性受到其包装类的限制Program——它的可访问域也是internal如此。

如果您将其更新为:

class Program
{
    static void Main(string[] args)
    {
    }
}

internal class A { }
public class B : A { }

它将抛出不一致的可见性编译器错误。或者如果你重新定义Program为 bepublic而不是internal它也会抛出错误。在这种情况下,B的可访问域现在public不再受Programinternal可访问域限制。


从 C# 规范3.5.2 Accessibility Domains

在程序 P 中以类型 T 声明的嵌套成员 M 的可访问域定义如下(注意 M 本身可能是一个类型):

如果 M 声明的可访问性是公共的,则 M 的可访问域是 T 的可访问域。

以及MSDN对 Accessibility Domain 的描述:

如果成员嵌套在另一种类型中,则其可访问域由成员的可访问级别和直接包含类型的可访问域共同决定。

如果包装类型Programinternal,则嵌套类型Bpublic具有 match 的可访问性Program,因此它被视为internal并且不会引发编译器错误。

于 2013-05-20T12:58:14.053 回答
0

当你用其他公共类继承私有类时,私有继承类不能在其他类中访问,那么它包含私有类的引用及其数据,所以这是不可能的。

abstract class test
    {
        public abstract void add();
        public int num1;
        public string str;
    }
class test3 : test1
    {
        public override void add()
        {
            throw new NotImplementedException();
        }
    }

两个类都是私有的。如果您使用 internal 那么您只能在程序集中访问。

于 2019-11-30T19:14:33.087 回答