下午在 RedHat Linux 9/MONO 1.0 中編譯了在以往 .net 項目中已經使用過的兩個類庫項目,其中第一個較簡單的項目順利編譯通過,在第二個XML類庫項目中出現編譯異常,而這個項目曾經經過微軟的CSC編譯器通過的啊,mono-mcs編譯器的反饋資訊如下:
XMLUtility.cs(73) error CS1502: The best overloaded match for method 'System.Xml.XmlAttribute System.Xml.XmlAttributeCollection.Remove(System.Xml.XmlAttribute)' has some invalid arguments.
XMLUtility.cs(73) error CS1503: Argument 0: Cannot convert from 'System.Xml.XmlNode' to 'System.Xml.XmlAttribute'.
XMLUtility.cs(73) error CS1501: No overload for method 'Remove' takes '1' arguments.
XMLUtility.cs(73) error CS8006: Could not find any applicable function for this argument list.
Compilation failed: 4 error(s), 0 warnings.
開啟偶的原始碼,定位到出錯提示位置,其上下文代碼如下:
提示:ownerNode 為函數的傳入參數,其類型為System.Xml.XmlNode,attributeName 為函數的傳入參數,其類型為String。
System.Xml.XmlNode attribute = ownerNode.Attribute.GetNamedItem(attributeName);
if(attribute != null)
ownerNode.Attributes.Remove(attribute);
將最後一句代碼改為:ownerNode.Attributes.Remove((System.Xml.Attribute)attribute); 後編譯成功!
為什麼在VS.net中以上代碼可以順利編譯通過,而在MONO的mcs編譯器中卻無法編譯通過呢?OK,先讓我們來看看mcs的提示資訊吧,大意是 在XmlAttributeCollection中沒有找到與之調用相匹配的Remove的重載方法。
通過VS.net的物件瀏覽器分別查看微軟的System.Xml.dll和Mono的System.Xml.dll庫檔案,其定義均一樣,如下:
public class XmlAttribute : System.Xml.XmlNode
public class XmlAttributeCollection : System.Xml.XmlNamedNodeMap
public virtual System.Xml.XmlAttributeCollection Attributes [get]
public virtual System.Xml.XmlAttribute System.Xml.XmlAttributeCollection.Remove(System.Xml.XmlAttribute node)
public virtual System.Xml.XmlNode System.Xml.XmlNamedNodeMap.GetNamedItem(string name)
在 XmlAttributeCollection 類中只有一個唯一的 Remove 方法,也無重寫(override)的重載。那麼最後那行代碼應該是編譯不過才對啊,為什麼在VS.net中又能通過呢?而且上面的.GetNamedItem(attributeName)調用返回的也只是 XmlNode 類型,因此編譯器無法就此而做出智能判斷,並預設進行轉換啊。唉,搞不懂CSC是如何處理的?
最後,在 Linux 中用mcs編譯出來的這個類庫大小是43KB,而在 Win2000 中用 VS.net(csc)(Debug/Release版)編譯出來的類庫卻有56KB。