跨语言互操作性

语言独立性有许多可能的含义。 文章 语言独立性和不依赖于语言的组件讨论一个,涉及无缝使用来自另一种语言编写的 app 的一种语言编写的类型。 第二含义是本文焦点,涉及将多个语言编写的代码添加到一个 .NET Framework 程序集。

以下示例通过创建一个名为 Utilities.dll 的类库说明跨语言互操作性,包括两个类、NumericLib 和 StringLib。 NumericLib 类在写入 C#,且 StringLib 类写入 Visual Basic。 以下是 StringUtil.vb 的源代码,该源代码包含在其 StringLib 类中一个成员ToTitleCase

Imports System.Collections.Generic
Imports System.Runtime.CompilerServices

Public Module StringLib
   Private exclusions As List(Of String) 

   Sub New()
      Dim words() As String = { "a", "an", "and", "of", "the" }
      exclusions = New List(Of String)
      exclusions.AddRange(words)
   End Sub

   <Extension()> _
   Public Function ToTitleCase(title As String) As String
      Dim words() As String = title.Split() 
      Dim result As String = String.Empty

      For ctr As Integer = 0 To words.Length - 1
         Dim word As String = words(ctr)
         If ctr = 0 OrElse Not exclusions.Contains(word.ToLower()) Then
            result += word.Substring(0, 1).ToUpper() + _
                      word.Substring(1).ToLower()
         Else
            result += word.ToLower()
         End If
         If ctr <= words.Length - 1 Then
            result += " "             
         End If   
      Next 
      Return result 
   End Function
End Module

以下是 NumberUtil.cs 的源代码,定义具有两个成员、 IsEven 和 NearZero 的 NumericLib 类。

using System;

public static class NumericLib 
{
   public static bool IsEven(this IConvertible number)
   {
      if (number is Byte ||
          number is SByte ||
          number is Int16 ||
          number is UInt16 || 
          number is Int32 || 
          number is UInt32 ||
          number is Int64)
         return ((long) number) % 2 == 0;
      else if (number is UInt64)
         return ((ulong) number) %2 == 0;
      else
         throw new NotSupportedException("IsEven called for a non-integer value.");
   }

   public static bool NearZero(double number)
   {
      return number < .00001; 
   }
}

若要在一个程序集打包两类,必须将其编译为模块。 若要编译Visual Basic 源代码文件到模块,请使用此命令:

vbc /t:module StringUtil.vb 

有关 Visual Basic 编译器命令的语法的更多信息,请参见 从命令行生成 (Visual Basic)

若要编译C#源代码文件到模块,请使用此命令:

csc /t:module NumberUtil.cs

有关 C# 编译器命令的语法的更多信息,请参见 在命令行上使用 csc.exe 生成

然后使用 Link tool (Link.exe)链接工具 (Link.exe) 将这两个模块编译为一个程序集:

link numberutil.netmodule stringutil.netmodule /out:UtilityLib.dll /dll 

然后,下面的示例调用 NumericLib.NearZero 和 StringLib.ToTitleCase 方法。 注意 Visual Basic 代码和 C# 代码都能访问两种类中的方法。

Module Example
   Public Sub Main()
      Dim dbl As Double = 0.0 - Double.Epsilon
      Console.WriteLine(NumericLib.NearZero(dbl))

      Dim s As String = "war and peace"
      Console.WriteLine(s.ToTitleCase())
   End Sub
End Module
' The example displays the following output:
'       True
'       War and Peace
using System;

public class Example
{
   public static void Main()
   {
      Double dbl = 0.0 - Double.Epsilon;
      Console.WriteLine(NumericLib.NearZero(dbl));

      string s = "war and peace";
      Console.WriteLine(s.ToTitleCase());
   }
}
// The example displays the following output:
//       True
//       War and Peace

若要编译Visual Basic 源代码,使用下面的命令:

vbc example.vb /r:UtilityLib.dll

若要编译 C#,将编译器的名称从 vbc 更改为 csc,并且将文件扩展名从 .vb 更改为 .cs。

csc example.cs /r:UtilityLib.dll

相关主题

标题

描述

语言独立性和与语言无关的组件

解释如何创建可由任何语言编写的 apps 使用的符合 CLS 的软件组件。

常规类型系统

描述公共语言运行时如何声明、使用和管理类型。

元数据和自描述组件

说明公共语言运行时描述类型并将描述信息存储于类型本身的机制。