2013-05-20 37 views
7

我正在阅读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 

尝试3:基本是内部和子是公共的(这工作,但它应该失败。由于基地是比子类

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

现在我的问题是,为什么尝试3没有失败不易进入的?子类是公共的,比基类,它是内部更容易。即使是书上说的THI s应该失败。但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() 
     { 
     } 
    } 
} 
+0

从技术上讲,可以通过[InternalsVisibleTo属性](http://msdn.microsoft.com/zh-cn/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx)暴露'internal' _can_以便在程序集外部使用也许这是它背后的推理。我会看看我是否可以在C#规范中找到特定条目。 –

+0

尝试3我的作品,即。无法编译时存在不一致的可访问性错误。 – amnezjak

+0

我也想到了InternalsVisibleTo属性,但是如果我没有在我的程序集文件中提到这个,该怎么办。必须有另一个原因。 –

回答

11

你把你的嵌套类另一个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 { } 

它会抛出不一致的知名度编译错误。或者,如果您重新定义Programpublic而不是internal它也会抛出错误。在这种情况下,B的辅助功能域现在为public,不再受限于Programinternal辅助功能域。


从C#规范3.5.2 Accessibility Domains

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

如果M的公开可访问性为M,则可访问性域为T的可访问性域。

和可访问域的MSDN's description

如果该成员嵌套在另一个类型内,其可访问域 由构件的两个可访问级别和立即包含类型的 访问域来确定。

如果包装类型Programinternal,则嵌套类型Bpublic将具有其可访问以匹配Program,从而它被当作internal和没有编译引发错误。

+0

是的,它现在失败了。我把它们放在程序课外。谢谢您的帮助。 –

+0

@FaisalHafeez我想我在C#规范中找到了描述这种行为的条目。好问题! –

+0

这里很好的使用这个规范。 –

相关问题