Dot-Net

COM/.NET 介面名稱中的非字母數字字元

  • December 1, 2010

我正在考慮使用字元#@!在我們的系統生成的一些 COM 介面中。COM 類型庫也導出到 .NET。這些角色以後會給我帶來麻煩嗎?

我今天大部分時間都對其進行了測試,一切似乎都很好。我們的系統會像往常一樣繼續工作。

我謹慎的原因是這些字元在 MIDL 中是非法的,它使用 C 語法作為類型名稱。但是我們不使用 MIDL - 我們使用 ICreateTypeInfo 和 ICreateTypeLib 建構我們的類型庫。看起來這只是 MIDL 限制,COM 和 .NET 對非字母數字字元感到滿意。但也許有一些我不知道的…

這就是我發現的。

我認為毫無疑問,這些名稱在 COM 中的二進制級別是合法的,因為 COM 介面的名稱是它的 IID,而文本名稱只是文件。

在 .NET 方面,相關規範是公共語言基礎設施規範(ECMA-335,http://www.ecma-international.org/publications/standards/Ecma-335.htm。)我想知道是 .NET 還是 Mono在上面添加自己的限制——這樣做會降低互操作性,但這是現實世界。

第 8.5.1 節介紹了通用類型系統中的有效類型名稱,並簡單地說名稱是使用程式碼點進行比較的。奇怪的是,它沒有說明名稱的組成,只說明名稱的比較方式。本節由 MSDN 在http://msdn.microsoft.com/en-us/library/exy17tbw%28v=VS.85%29.aspx解釋,其中說唯一的兩個限制是 (1) 類型名稱是“編碼為 Unicode(16 位)字元的字元串”,並且 (2) 它們不能包含嵌入的 0x0000。

我引用了關於 16 位 Unicode 的內容,而不是對其進行解釋,因為它使用了不精確的語言。據推測,該頁面的作者指的是 UTF-16。在任何情況下,ECMA-335 都指定了逐字節比較,並且沒有提及 Unicode(關於類型名稱),也沒有禁止嵌入零。也許.NET 已經偏離了這裡的 CTS,儘管我對此表示懷疑。更有可能的是,這個 MSDN 頁面的作者在編寫它時正在考慮程式語言。

公共語言規範(也在 ECMA-335 中定義)定義了原始碼中標識符的規則。標識符與我的問題沒有直接關係,因為我的內部類型名稱從未出現在原始碼中,但我還是調查了它。CLS 是 CTS 的一個子集,因此它的限制不一定是更廣泛的 CTS 的一部分。CLS 規則 4 規定標識符必須遵循 Unicode 標準 3.0 技術報告 15 附件 7 的規則 - 請參閱http://www.unicode.org/reports/tr15/tr15-18.html。該文件也有點模糊,因為它提到“其他字母”和“連接標點符號”,但沒有定義它們。這有幫助: http: //notes.jschutz.net/topics/unicode/

ECMA 規範的第 8.5.1 節包含一個非規範性註釋,即 CLS 使用者(我想,例如 C# 或 Visual Studio 類型的瀏覽器)“不需要使用違反 CLS 規則 4 的類型”。我提議的介面名稱確實違反了規則 4。該註釋似乎暗示有效類型的名稱可能違反規則 4,並且 CLS 使用者應該接受流氓名稱或安全地忽略它。(Visual Studio 類型的瀏覽器毫無怨言地顯示它。)

所以我提議的類型名稱在原始碼中通常是非法的。但請注意,第 10.1 節(關於 CLS 中的標識符)說“由於其規則僅適用於導出到其他語言的項目,因此未從程序集導出的私有成員或類型可以使用他們選擇的任何名稱。”

我的結論是使用字元#@ 是安全的!在我的類型名稱中,只要它們保留在二進制域中並且永遠不需要出現在原始碼中或程序集之外。事實上,它們從未在 COM 伺服器之外使用過。

關於面向未來的一句話…… CTS 對類型名稱的組成幾乎沒有什麼可說的,儘管有一個名為“有效名稱”的部分(第 8.5.1 節)。他們將來可能會改變這一點,但是這個廣泛而自由的規範已經邀請我們所有人做我們喜歡做的事情。如果 CTS 的設計者想要為改變留出空間,那麼他們肯定會為此做出一些規定,或者至少不那麼慷慨。

引用自:https://stackoverflow.com/questions/4161896