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


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

    1. 所有publicprotected的成员方法的参数和返回值必须是符合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)

    {

    }

     

    1. 所有那些不符合CLS标准的publicprotected成员方法,都应有符合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标准来构建就可以了,把转换封装到接口中,这样产出比还是很可以接受的。 :)

  • 相关阅读:
    nginx防止盗链
    Nginx防盗链详细设置
    [bzoj2127]happiness
    [bzoj2400]Optimal Marks
    [bzoj1738]发抖的牛
    [bzoj1741]穿越小行星群
    [bzoj3123]森林
    [bzoj2588]Count on a tree
    [bzoj3144]切糕
    [bzoj1787]紧急集合
  • 原文地址:https://www.cnblogs.com/haokaibo/p/2147537.html
Copyright © 2020-2023  润新知