2009-04-08 12 views
25

我發現下面的代碼:爲什麼c#編譯器從這段代碼創建一個PrivateImplementationDetails?

public static class MimeHelper 
    { 
     public static string GetMimeType(string strFileName) 
     { 
      string retval; 
      switch (System.IO.Path.GetExtension(strFileName).ToLower()) 
      { 
       case ".3dm": retval = "x-world/x-3dmf"; break; 
       case ".3dmf": retval = "x-world/x-3dmf"; break; 
       case ".a": retval = "application/octet-stream"; break; 
       // etc... 
       default: retval = "application/octet-stream"; break; 
      } 
      return retval; 
     } 
    } 

導致編譯器來創建此namespaceless,內部類(從反射器複製):

<PrivateImplementationDetails>{621DEE27-4B15-4773-9203-D6658527CF2B} 
    - $$method0x60000b0-1 : Dictionary<String, Int32> 
    - Used By: MimeHelper.GetMimeType(String) : String 

這是爲什麼? 我怎麼會改變上面的代碼,因此不會發生(只是出於興趣)

感謝

安德魯

+1

作爲題外話,你爲什麼要使用額外的字符串變量retval,如果你可以立即從開關返回? – abatishchev 2009-04-08 12:09:51

+0

,因爲它是從某處複製和粘貼作業,是的,我可以(也會)改變它的做法 – 2009-04-08 12:12:11

回答

22

它創建字典來處理各種情況的查詢switch語句而不是使用幾個分支if來設置返回值。相信我 - 你不想改變它的做法 - 除非你想讓地圖明確。

ASIDE:我原本以爲這個詞典存儲了一個從每個case到一個索引的映射到另一個映射的返回值。根據@Scott(請參閱評論),它實際上將一個索引存儲到應該爲該情況執行的代碼的標籤中。如果考慮到針對每種情況執行的代碼可能有所不同,並且可能比給出的示例中的代碼長得多,這是絕對有意義的。

編輯:基於您的評論,我想我可能會嘗試映射存儲在外部配置文件中,讀取他們在啓動時,構建實際的地圖 - 無論是從關鍵的單級地圖以從鍵到索引和索引到值的價值或類似的多級地圖。我認爲在配置文件中維護這些映射會比在每次需要添加或刪除特定情況時更新代碼更容易。例如,

4

發生什麼事是編譯器正在編譯時創建一個內部類。這個類被稱爲<PrivateImplementationDetails>{99999999-9999-9999-9999-999999999999},這個類的GUID組件是在編譯時生成的,所以它隨每個構建而變化。在這個類的內部有一個包含不同大小寫變量的字典,以及一個對應於每個值的int。然後它用字典中的查找替換switch語句以獲取相應的int,並在int值上進行切換(比執行一堆sting比較更有效)。

相關問題