【转】CLS(公共语言规范)的CLSCompliant(跨语言调用)

出处:http://www.cnblogs.com/zhangchenliang/archive/2012/08/29/2662395.html

.net的一个很重要的特性就是跨语言的编程,用C#写的dll可以在VB.net里调用,例如:
用C#写的一个类,编译到dll中,然后在VB.net中调用:

 

using System;

namespace CLSsample
{
 public class CLSTest
 {
  public CLSTest()
  {
   
  }

  public void ABC()
  {
   Console.WriteLine("ABC");
  }

 }

}

 

在VB.net中调用:
Dim c As CLSsample.CLSTest = New CLSsample.CLSTest
c.ABC()

现在给dll中的CLSTest类加一个函数:
public void abc()
{
 Console.WriteLine("abc");
}
先编译C#写的这个dll,再编译VB.net工程,编译出现问题,提示信息如下:

重载决策失败,原因是没有可访问的“ABC”最适合这些参数: 
    'Public Sub abc()': 不是最适合。
    'Public Sub ABC()': 不是最适合。

    
原因很简单,因为C#是区分大小写的,但是VB.net不区分。
而真正的原因在于用C#写的这个类是不符合CLS(公共语言规范)的。
现在在命名空间前面加上一句,标示编译时确保不包含其它语言无法使用的内容:
[assembly:CLSCompliant(true)]
namespace CLSsample
{
   ......
   public void ABC()
  {
       Console.WriteLine("ABC");
  }
   public void abc()
  {
       Console.WriteLine("abc");
  }
}
这时候再编译,就会出现错误,提示信息:
只在大小写不同的标识符“CLSsample.CLSTest.abc()”不符合 CLS

要编译通过,在函数abc前加上:
[CLSCompliantAttribute(false)]
指出 abc函数 是不符合 CLS 的

下面是MSDN中对CLS的部分说明:
CLS 在设计上足够大,可以包括开发人员经常需要的语言构造;同时也足够小,
大多数语言都可以支持它。此外,任何不可能快速验证代码类型安全性的语言
构造都被排除在 CLS 之外,以便所有符合 CLS 的语言都可以生成可验证的代码
(如果它们选择这样做)。

也就是说开发的类库必须遵守CLS才可以更好的被其它的语言所使用。否则就像
上面的情况,用C#开发的动态链接库在VB.net中就出现了问题,特别是开发一些
通用的类库的时候,就更需要注意这一点。

看看对.net framework中Int32反编译的部分结果(用的是Reflector):
[CLSCompliant(false)]
uint System.IConvertible.ToUInt32(IFormatProvider provider);
这是因为有的语言不支持UInt32类型。

再看看对UInt32反编译的结果,UInt32的声明:
[Serializable, StructLayout(LayoutKind.Sequential), CLSCompliant(false)]
public struct UInt32 : IComparable, IFormattable, IConvertible
{
}

什么是CLS? 
“CLS是编程语言设计者和类库设计者之间的一个约定”


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中的Attribute是一种可用于为程序元素(如类、方法、属性等)添加元数据的标记。它们可以用来提供信息,例如代码中的注释、编译器指令、运行时行为等。 以下是C#中常用的Attribute用法大全: 1. [Obsolete]:表示代码已过时,不应再使用。 2. [Serializable]:指示该类可以被序列化为二进制流,可以保存到文件或数据库中。 3. [DataContract]:用于指示该类可用于数据序列化,例如在Web服务中使用。 4. [DataMember]:用于标记序列化的数据成员。 5. [XmlRoot]:用于指示XML序列化时的根元素名称。 6. [XmlType]:用于指示XML序列化时的类型名称。 7. [XmlIgnore]:用于指示在XML序列化时忽略某个属性或字段。 8. [DllImport]:用于指示在C#中使用外部函数库。 9. [Conditional]:用于指示当某个条件为真时才编译特定的代码。 10. [MethodImpl]:用于指示方法的实现方式,例如是否为内联函数。 11. [ThreadStatic]:用于指示某个静态字段是线程本地的,每个线程都有自己的副本。 12. [AttributeUsage]:用于指示Attribute的使用方式和目标。 13. [CLSCompliant]:用于指示该代码符合公共语言规范。 14. [Conditional("DEBUG")]:用于指示只在调试模式下编译特定的代码。 15. [DebuggerStepThrough]:用于指示调试器不要在该方法中断。 16. [DefaultMember]:用于指示该类的默认成员,例如在集合类中,可以通过索引访问元素。 17. [DefaultValue]:用于指示某个成员的默认值。 18. [Description]:用于指示某个成员的说明文本,在属性窗口中显示。 19. [DisplayName]:用于指示某个成员的显示名称,在属性窗口中显示。 20. [EditorBrowsable]:用于指示某个成员是否在属性窗口中可见。 21. [Obsolete("message")]:用于指示代码已过时,提供一条说明信息。 22. [SerializableAttribute]:用于标记可以序列化的类。 23. [NonSerialized]:用于标记不需要序列化的字段。 24. [XmlArray]:用于指示序列化为XML时的数组名称。 25. [XmlArrayItem]:用于指示序列化为XML时的数组元素名称。 26. [XmlEnum]:用于指示序列化为XML时的枚举名称。 27. [XmlInclude]:用于指示序列化为XML时包含某些类型。 28. [XmlElement]:用于指示序列化为XML时的元素名称。 29. [XmlAttribute]:用于指示序列化为XML时的属性名称。 30. [Serializable]:用于标记可序列化的类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值