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

摘要:
原因很简单,因为C#区分大小写,但VB.net不区分大小写。真正的原因是用C#编写的类不符合CLS。此外,任何无法快速验证代码类型安全性的语言构造都将从CLS中排除,这样所有符合CLS的语言都可以生成可验证的代码。也就是说,开发的类库必须符合CLS才能更好地被其他语言使用。查看中Int32反编译的一些结果。netframework:[CLSCompliant]uintSystem.IConvertible。ToUInt32;这是因为某些语言不支持UInt32类型。

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

CLS(公共语言规范)的CLSCompliant(跨语言调用)第1张using System;
CLS(公共语言规范)的CLSCompliant(跨语言调用)第1张
CLS(公共语言规范)的CLSCompliant(跨语言调用)第1张namespace CLSsample
CLS(公共语言规范)的CLSCompliant(跨语言调用)第4张{
CLS(公共语言规范)的CLSCompliant(跨语言调用)第5张 public class CLSTest
CLS(公共语言规范)的CLSCompliant(跨语言调用)第6张 {
CLS(公共语言规范)的CLSCompliant(跨语言调用)第5张  public CLSTest()
CLS(公共语言规范)的CLSCompliant(跨语言调用)第6张  {
CLS(公共语言规范)的CLSCompliant(跨语言调用)第5张   
CLS(公共语言规范)的CLSCompliant(跨语言调用)第10张  }
CLS(公共语言规范)的CLSCompliant(跨语言调用)第5张  public void ABC()
CLS(公共语言规范)的CLSCompliant(跨语言调用)第6张  {
CLS(公共语言规范)的CLSCompliant(跨语言调用)第5张   Console.WriteLine("ABC");
CLS(公共语言规范)的CLSCompliant(跨语言调用)第10张  }
CLS(公共语言规范)的CLSCompliant(跨语言调用)第10张 }
CLS(公共语言规范)的CLSCompliant(跨语言调用)第16张}
CLS(公共语言规范)的CLSCompliant(跨语言调用)第1张

在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是编程语言设计者和类库设计者之间的一个约定”

       [ CLSCompliant(false)]
        public void CreateItem(EnvDTE.DTE dte) {
            this.creator.CreateDataAccessTechnologyObject(this, dte);
        }

免责声明:文章转载自《CLS(公共语言规范)的CLSCompliant(跨语言调用)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Alexa世界排名原理+作弊源码,为网站赢得好排名轮播(Carousel)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【面试题】新东方.NET工程师面试题总结

1、学校几本(是否统招)、英语等级、大学成绩排名Top%几、当前月薪(入职前是否能提供薪资证明材料)、期望月薪 二本,统招英语四级排名top10 2、做过的项目技术栈是什么?(例如 .NET、Sql Server、Dapper、EF、Redis……) .NET、C#、EF、MVC、SQL Server、Oracle、WebService、API、SDK、R...

C# OCX控件之开发

在C#中,其实没有OCX控件一说,相对应的只是COM组件,编译后也是.DLL,而不是.ocx.所以在C#中,在创建项目时只能创建类库项目。 然后就是具体的代码开发。(略) 要使组件成为能被网页脚本调用的OCX控件,在开发时,要注意以下几点: 1、必须要为将发布OCX控件的主类设置GUID码。该码在创建类库时,C#会自动生成一个(你可以使用,也可以重新生成)...

C#: static关键字的作用(转)

C#: static关键字的作用  static意思是静态,可以修饰类、字段、属性、方法 标记为static的就不用创建实例对象调用了,可以通过类名直接点出来 static三种用法: 1.用于变量前,表示每次重新使用该变量所在方法、类或自定义类时,变量的值为程序这次运行最后一次为变量赋值时的值,这个方法称为静态函数: private void s() {...

C# 中使用JSON

C#中使用JSON不需要使用第三方库,使用.NET Framwork3.5自带的System.Runtime.Serialization.Json即可很好的完成JSON的解析。 关于JSON的入门介绍见(首页的图很形象): http://www.json.org/  一、Using 需要添加引用:System.ServiceModel.Web 和 Syst...

C#的dll被其他程序调用时,获取此dll正确的物理路径

    当C# dll被其他程序调用时,用Application.StartupPath获取的dll路径并不一定是此dll的物理路径,有可能是调用程序的路径。 以下方法或者能够获取dll正确的物理路径(未经过严格验证): //获取到文件完整路径 string path = Assembly.GetExecutingAssembly().Location;...

第一次开发电商项目

先讲一下工作经历吧,09年上大四时就偷跑到北京做开发(moss),10年大学毕业后正式来北京。先做了近两年的网络教育平台开发,后来跳到一家物联网创业公司,做了两年的C# 仓储物流、手持机、RFID设备软件的开发。个人觉得再这样下去技术杂而不精今年3月份就跳到了现在的这家电商创业公司。 其实进入这家公司之前也曾经犹豫过,因为开的工资太低了,比普通行业C#开发...