第二個規則是取決與你自己的:你必須確保所有公共的及受保護的操作是語言無關的。同時你還要保證你所使用的多態接口中沒有隱藏不兼容的對象。
操作符重載這個功能,有人喜歡有人不喜歡。同樣,也並不是所有的語言都支持操作符重載的。CLS標准對於重載操作符這一概念即沒有正面的支持也沒有反正的否定。取而代之是,它為每個操作符定義了一了函數:op_equals就是=操作符所對應的函數名。op_addis是重載了加號後的函數名。當你重載了操作符以後,操作符語法就可以在支持操作符重載的語言中使用。如果某些開發人員使用的語言不支持操作符重載時,他們就必須使用op_這樣的函數名了。如果你希望那些程序員使用你的CLS兼容程序集,你應該創建更多的方便的語法。介此,推薦一個簡單的方法:任何時候,只要重載操作運算符時,再提供一個等效的函數:
// Overloaded Addition Operator, preferred C# syntax:
public static Foo Operator+( Foo left, Foo right)
{
// Use the same implementation as the Add method:
return Foo.Add( left, right );
}
// Static function, desirable for some languages:
public static Foo Add( Foo left, Foo right)
{
return new Foo ( left.Bar + right.Bar );
}
最後,注意在使用多態的接口時,那些非CLS的類型可能隱藏在一些接口中。最容易出現的就是在事件的參數中。這會讓你創建一些CLS不兼容的類型,而在使用的地方卻是用與CLS兼容的基類。
假設你創建了一個從EventArgs派生的類:
internal class BadEventArgs : EventArgs
{
internal UInt32 ErrorCode;
}
這個BadEventArgs類型就是與CLS不兼容的,你不可能在其它語言中寫的事件句柄上使用這個參數。但多態性卻讓這很容易發生。你只是申明了事件參數為基類:EventArgs:
// Hiding the non-compliant event argument:
public delegate void MyEventHandler(
object sender, EventArgs args );
public event MyEventHandler OnStuffHappens;
// Code to raise Event:
BadEventArgs arg = new BadEventArgs( );
arg.ErrorCode = 24;
// Interface is legal, runtime type is not:
OnStuffHappens( this, arg );
以EventArgs為參數的接口申明是與CLS兼容的,然而,實際取代參數的類型是與CLS不兼容的。結果就是一些語言不能使用。
最後以如何實現CLS兼容類或者不兼容接口來結束對CLS兼容性的討論。兼容性是可以實現的,但我們可以更簡單的實現它。明白CLS與接口的兼容同樣可以幫助你完整的理解CLS兼容的意思,而且可以知道運行環境是怎樣看待兼容的。
這個接口如果是定義在CLS兼容程序集中,那麼它是CLS兼容的:
[ assembly:CLSCompliant( true ) ]
public interface IFoo
{
void DOStuff( Int32 arg1, string arg2 );
}