1. 程式人生 > >C#中Internal關鍵字的總結

C#中Internal關鍵字的總結

注意:想要徹底把Internal關鍵字搞清楚,就耐著性子把她讀完。當然了這篇文章只是對其他文章的總結。也算是引用吧。主要還是為了把知識點搞清楚


進入主題之前先來了解一下,專案、解決方案、程式集、名稱空間四個容易混淆的概念。
①專案:就是我們開發的一個軟體。.NET下,專案有多種型別,如控制檯、Windows應用程式、類庫、Web應用程式等等。經過編譯後,會生成.exe檔案和.dll檔案。 .exe檔案有統一的主程式入口,
可以被執行,而類庫只是提供一些功能給其他專案呼叫。
②解決方案:當我們在VS中新建任何一種型別專案時,這個專案還屬於一個解決方案。當我們的業務相對簡單時,解決方案所發揮的作用並不是很大。但當我們開發複雜的軟體時,需要多個模組組成。
比如說開發中常用的三層架構,U層是一個簡單的windows應用程式(專案的一種型別)、B、D層由多個類庫(專案的另一種型別)組成。通過一個解決方案,我們就可以將其(多個專案)組合起來,完成我們的開發。
形象地說,解決方案就是一個容器,在這個容器裡,分成好多層,好多格,用來存放不同的專案。換句話來說:就是《程式集就是一個專案,多個專案構成一個解決方案》
③程式集:一個專案就是一個程式集。一個程式集可以體現為一個dll檔案,或者exe檔案。
④名稱空間:主要是為了避免一個專案中,可能會存在的相同物件名的衝突。


對於編輯來說,名稱空間僅僅是在型別名稱前加了一些由點號隔開的符號而已.這使得一個型別的名稱更長,從而也更具惟一性.如果兩個相同的類在同一個名稱空間則會衝突,如果不同的名稱空間有相同的型別,
也會產生二義性。


注意,C#的using指示符會指示編譯器試著在型別名上新增不同的字首,直到找到一個匹配為止,名稱空間只是邏輯上,真正的型別在程式集裡,當查詢一個型別的定義時,編譯器必須被告知到哪些程式集中進行查詢,
編譯器將掃描它知道的所有程式集來查詢型別的定義.一旦編譯器找到了正確的程式,程式集資訊和型別資訊會被新增到生成託管模組的元資料中。


   重要提示:CLR不知道名稱空間的任何事情。訪問一個型別時,CLR需要知道型別的完整名稱(這可能是一個相當長、包含句點符號的名稱)以及該型別的定義具體在哪一個程式集中。
這樣一樣,“執行時”才能載入正確的程式集,找到目標型別,並對其進行操作。


二、聯絡與區別


1、名稱空間是類庫的邏輯組織形式,程式集就是類庫的物理組織形式。
2、一個程式集內可能有多個名稱空間,一個名稱空間可能存在於不同的程式集中
3、程式集是實現型別的檔案,編譯之後生成的。 
  名稱空間是對型別的邏輯分組。 
4、c#編譯器可能比較關心名稱空間,應為它需要確定類的完整名稱,然後交給CLR。 
 CLR只關心程式集,會通過類的完整名稱載入對應的程式集。


三、總結


   通過在專案中使用分部類,發現可以通過分部類實現對這個類的擴充和完善。而使用分部類時我們會對名稱空間進行修改,近而將類進行擴充套件;這就是我們說的一個名稱空間可以存在於不同的程式集。
通過專案去不斷成長,努力去做,《關於分部類的介紹可以訪問下面地址:https://msdn.microsoft.com/zh-cn/library/wa80x488.aspx 》


1. internal(內部):限定的是隻有在同一程式集中可訪問,可以跨類
    protected(受保護):限定的是隻有在繼承的子類中可訪問,可以跨程式集
    protected internal:受保護“或”內部修飾符修飾成員,當父類與子類在同一個程式集中,internal成員可見。當父類與子類不在同一個程式集中,子類不能訪問父類internal成員,而子類可以訪問父類的ptotected internal成員,
    即從當前程式集或從包含類派生的型別,可以訪問具有訪問修飾符 protected internal 的型別或成員。


2. internal 關鍵字是型別和型別的成員 訪問修飾符。只有在同一程式集的檔案中,內部型別或成員才是可訪問的
內部訪問通常用於基於元件的開發,因為它使一組元件能夠以私有方式進行合作,而不必嚮應用程式程式碼的其餘部分公開。
   例如,用於生成圖形使用者介面的框架可以提供 Control 和 Form 類,這兩個類通過使用具有內部訪問許可權的成員進行合作。
   由於這些成員是內部的,它們不向正在使用框架的程式碼公開。


3. 從定義具有內部訪問能力的型別或成員的程式集外部引用該型別或成員是錯誤的。
此示例包含兩個檔案(表示兩個檔案不在同一個程式集中):Assembly1.cs 和 Assembly1_a.cs。第一個檔案包含內部基類 BaseClass。在第二個檔案中,例項化 BaseClass 的嘗試將產生錯誤。
// Assembly1.cs
// Compile with: /target:library
internal class BaseClass 
{
   public static int intM = 0;
}
// Assembly1_a.cs
// Compile with: /reference:Assembly1.dll
class TestAccess 
{
   static void Main() 
   {
      BaseClass myBase = new BaseClass();   // 錯誤,沒法例項化
   }
}


在此示例中,使用與示例 1 中所用的檔案相同的檔案,並將 BaseClass 的可訪問性級別更改為 public。還將成員 IntM 的可訪問性級別更改為 internal。在此例中,你可以例項化類,但不能訪問內部成員。
// Assembly2.cs
// Compile with: /target:library
public class BaseClass 
{
   internal static int intM = 0;
}
// Assembly2_a.cs
// Compile with: /reference:Assembly1.dll
public class TestAccess 
{
   static void Main() 
   {
      BaseClass myBase = new BaseClass();   // Ok.可以例項化類
      BaseClass.intM = 444;    // 產生錯誤,因為不能訪問內部成員
   }
}