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标准来构建就可以了,把转换封装到接口中,这样产出比还是很可以接受的。 :)
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标准来构建就可以了,把转换封装到接口中,这样产出比还是很可以接受的。 :)
相关文章推荐
- Effective C# 学习笔记(十六)尽量少的创建对象,给GC减减负
- Effective C# 学习笔记(十七)标准析构模式的实现
- Effective C# 学习笔记(二十八)创建基于网络分布式部署的APIs
- Effective C# 学习笔记(五) 最好重载你所创建类的ToString()方法
- 2.2 符合标准的浏览器 - 网站重构与Web标准设计 - 学习笔记
- 第三讲:C++基础语法 & 创建第一个场景 ------学习笔记
- 【Git学习笔记】创建版本库
- Fiori学习笔记 - Eclipse创建一个SAP UI5工程
- Java Web 学习笔记(四) 基于 SpringMVC+BootStrap 创建WebApp
- VC++学习笔记之MFC应用程序创建/执行顺序和MFC运行机制
- SAP标准培训课程C4C10学习笔记(二)第二单元
- Windows内核学习笔记(六)-- [总结]创建IRP的四种不同方式
- ROS学习笔记五:创建library
- Vue学习笔记一:使用vue-cli 创建开发环境
- 韩顺平 javascript教学视频_学习笔记13_类和对象细节_创建对象的几种方式_js对象内存分析
- Effective C#学习笔记:适当使用.NET运行时诊断
- C++Primer学习笔记第八章(8/18)标准IO库
- C++编程思想学习笔记---第13章 动态创建对象
- Linux内核学习笔记之进程创建(十)
- C++ Primer学习笔记- 第三章:标准库类型之三