2013-05-20 38 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

這裏很好的使用這個規範。 –

相關問題