您的位置:首页 > Web前端

Effective C# 学习笔记(四十九)创建符合CLS标准的程序集

2011-08-20 22:38 344 查看
符合CLS(Common Language
Subsystem)标准的程序集可以被其他跑在CLR的语言公用,这是.NET的一个引以为傲的特性,这样你用一种语言编写的程序集就可以被其他在CLR同样支持的程序调用了。要实现这个效果,要求更多的时间来设计构建你的程序集。主要要求两点:

所有public和protected的成员方法的参数和返回值必须是符合CLS标准的。你只需在你的程序集属性上添加如下属性声明即可:

[assembly:
System.CLSCompliant(true)]

这样声明后,你的程序集在编译时就会检查你里边的代码是否是符合CLS标准的。例如下面的两段代码由于UInt32类型并不支持CLS标准,就会在编译时报错。

//
Not CLS Compliant, returns unsigned int:

public
UInt32 Foo()

{

return
foo;

}

//
Not CLS compliant, parameter is an unsigned int.

public
void Foo2(UInt32 parm)

{

}

所有那些不符合CLS标准的public和protected成员方法,都应有符合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标准的影响,下面的代码中的BasEventArgs类继承自符合CLS标准的类型EventArgs,但其内部有一个公有属性ErrorCode,其类型为
UInt32,不被CLS标准支持,所以当使用该类型(BadEventArgs)来做参数的方法或委托就不是符合CLS标准的了,如下代码所示:

public
class BadEventArgs : EventArgs

{

public
UInt32 ErrorCode;

}

//
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);//这里在编译时不出错,但在运行时就不符合CLS标准规范了

再来看一个例子:

public
interface IFoo2

{

//
Non-CLS compliant, Unsigned int

void DoStuff(UInt32 arg1, string arg2);//不符合CLS规范的方法

}

public
class MyClass2 : IFoo2

{

//
explicit interface implementation.

//
DoStuff() is not part of MyClass's public interface

void
IFoo2.DoStuff(UInt32 arg1, string arg2)

{

//
content elided.

}

}

上面的代码定义了一个不符合CLS标准的方法IFoo2,其方法DoStuff(UInt32 arg1, string
arg2)由于参数类型的原因,不符合规范。而MyClass2继承自该接口,并显示的实现了该方法。但对于MyClass2来说其还是符合CLS规范的,因为DoStuff方法的调用,是属于IFoo2的。也就是说在使用该类型的对象的DoStuff方法时,你需要先把该对象显示的转换为IFoo2的对象才能使用。也就是你只能这么调用DoStuff方法:

MyClass2
myClass2 = new MyClass2();

(myClass2
as IFoo2).DoStuff(1, "hello compliance");

总结:实现CLS标准的程序集可以被其他运行在CLR平台的语言调用,但是要付出一点设计和构建的努力。当然,也不是说你所有的程序集都要为了这个目标去构建,你只需在需要多语言交互的接口使用符合CLS标准来构建就可以了,把转换封装到接口中,这样产出比还是很可以接受的。 :)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: