65.9K
CodeProject 正在变化。 阅读更多。
Home

Microsoft .NET 快速入门 第 3 章:使用 .NET 编程

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.67/5 (6投票s)

2004 年 2 月 19 日

24分钟阅读

viewsIcon

51688

.NET 编程简介。

Sample Image - 0672325748c.jpg
作者 Hitesh Seth
标题 Microsoft .NET 快速入门
出版社 Sams
出版日期 2003 年 12 月 24 日
ISBN 0672325748
价格 34.99 美元
页数 504

使用 .NET 编程

本章内容

引言

使用 Visual Studio 和 COM/OLE 技术的 Microsoft 开发人员一直享受着为应用程序和组件开发选择编程语言的好处。嗯,差不多吧。(例如,用一种编程语言开发的组件不能“继承”自另一种编程语言。)随着 CLR 和 .NET Framework 的引入,为 .NET 组件和应用程序选择任何受支持的编程语言的这种灵活性仍然是一个关键要求。开箱即用,.NET Framework 和支持开发的关键工具 Visual Studio .NET 支持四种编程语言:Visual C#、Visual Basic .NET、托管 C++(也称为 Visual C++ .NET)和 Visual J#。此外,由于 CLR 已经被公认为一个发展中的标准,第三方独立软件供应商 (ISV) 和研究人员可以“移植”其他编程语言以编译到 .NET 运行时。

这种编程灵活性的出现有两个原因:灵活性、易于迁移和技能重用。例如,全球数百万 Visual Basic 开发人员可以选择 Visual Basic .NET 编程语言来利用和增强他们现有的技能;C++ 和 Java 开发人员可以选择使用托管 C++、Visual J# 或新的创新 C# 编程语言。所有四种编程语言都有相似的共同特性;大多数可以用于实现相似的结果。然而,每种语言都有其自身的优点和差异,但大多数差异在于语言语法。

本章简要讨论四种编程语言。对每种编程语言的所有功能的完整描述本身就值得一本书;事实上,有多套书籍分别讨论每种语言。本章的其余部分采用动手实践、深入代码的风格来介绍编程语言。每个语言部分都分为相似的部分

  • Hello World
  • 注释
  • 数据类型
  • 枚举
  • 数组
  • 变量和常量
  • 表达式
  • 语句
  • 继承
  • 接口
  • 异常处理
  • 事件
  • 委托(Delegates)

您将使用示例程序,通过实践来理解各种编程语言的关键功能。

C#

C# 编程语言(发音为“C sharp”)随 .NET Framework 一起引入。它代表了编程语言开发领域的一个里程碑。尽管新的 C# 语言起源于 Java 和 C++ 等现有编程语言,但它代表了最具创新性、最现代、甚至在大多数领域都是首选的 .NET 编程语言。C# 的引入是为了结合 Visual Basic 和 C++ 的关键价值。Visual Basic 具有易用性和高开发人员生产力,而 C++ 代表了 ultimate 的灵活性和控制力。C# 将两者融合;它相对比 C++ 简单(没有指针、模板等),并且它具有 C++ 的所有优良面向对象特性和 Visual Basic 的易用性。不再需要特定的内存分配,因为所有内容都由公共运行时进行“垃圾回收”。在多种方面,C# 也与 Java 编程语言相似,Java 编程语言也获得了广泛的开发人员支持。然而,Java 旨在成为一种平台中立的编程语言,编译成字节码,然后在虚拟机上执行,而 C# 程序(像所有 .NET 编程语言一样)被编译成 MSIL(Microsoft 中间语言),并且像所有应用程序一样,最终在执行前被转换为机器代码。


C# 编程语言:标准 - .NET 平台的一个关键方面是它基于现有和新标准之上。例如,C# 编程语言已被批准为 ISO 标准 (23270)。有关标准化倡议和标准本身的更多详细信息,请访问 http://msdn.microsoft.com/net/ecma/


C# 遵循**代码优先**模型,面向喜欢现代编程语言的简洁性但通常更喜欢手动编写程序而不是使用向导生成的开发人员。这使得代码更容易被其他开发人员理解,从而实现更简单的重用。C# 编程语言的主要特点如下:

  • Visual Basic 的易用性与大多数 C++ 功能的强大结合
  • C++ 和 Java 开发人员相似的编程语言语法
  • 支持所有 CLR 数据类型
  • 参数按引用和按值传递
  • 运算符重载(Java 中没有)
  • 能够运行明确标记的“不安全”代码
  • 基于 XML 的文档,使用特殊注释
  • 与 Visual Studio .NET 集成,实现快速开发

Hello World

在本节中,您将了解一个 Hello World C# 程序。每个 C# 应用程序都由一个类组成。如果它是一个可执行应用程序,则可用的类之一应该有一个静态的 Main() 方法作为入口点。(如果 Main 未声明或声明不当,编译器会发出警告。)Main 方法是重载的,并且可以传递一个 String 数组作为任何命令行参数。

using System;
namespace hks
{
  public class HelloWorld
  {
   public static void Main()
   {
     Console.WriteLine("Hello World in C#");
   }
  }
}

C# 类存储在 .cs 文件中。将上述程序保存到一个文件(例如 HelloWorld)后,您可以将程序编译成 .NET 可执行文件。您需要将 .NET Framework SDK 的 *bin* 文件夹包含在您的 *PATH* 变量中。如果您安装了 Visual Studio .NET,您会在 Visual Studio .NET 工具下找到一个名为 Visual Studio .NET 2003 命令提示符的快捷方式。此快捷方式会初始化所有环境变量,并提供对命令行编译器的访问。

csc HelloWorld.cs

现在输入 *HelloWorld.exe* 运行应用程序,您应该会在屏幕上看到“Hello World in C#”的回显。

注释

C# 提供了几种在程序中引入注释的方式;最流行的两种是传统的单行注释 (//) 和多行注释 (/* */)。此外,C# 还提供了基于 XML 的注释,可用于从一组代码文件中创建 XML 文档。然后可以使用 XSLT(XML 样式表语言)处理这些 XML 文件,以转换为在线 HTML 文档等。

using System;
namespace hks
{
    /// <summary>
    /// A Simple Class
    /// </summary>
    public class Comments
    {
        public static void Main()
        {
        // A Simple comment
        /*
         A multi
         line comment
        */
          Console.WriteLine("Hello World in C#");
        }
    }
}

数据类型

表 3.1 描述了 C# 类型如何映射到相应的 .NET Framework 类型。从真正的意义上说,C# 关键字实际上是 .NET 类型的紧凑表示。

表 3.1 C# 数据类型

C# 类型 对应的 .NET Framework 类型
Bool System.Boolean
byte, sbyte System.Byte, System.SByte
Char System.Char
decimal, double, single System.Decimal, System.Double, System.Single
short, ushort, int, uint, long, ulong System.Int16, System.UInt16, System.Int32, System.UInt32, System.Int64, System.UInt64
对象 System.Object
字符串 System.String

枚举

C# 提供了枚举编程构造,它以人类可读的形式提供了一系列相关的常量值。

using System;
namespace hks
{
  public class UseEnumerations
  {
    enum CreditCard
    {
      Visa = 0,
      MasterCard = 1,
      AmericanExpress = 2,
      Discover = 3
    }
    public static void Main()
    {
      CreditCard mycard = CreditCard.Discover;
      Console.WriteLine(mycard);
      Console.WriteLine((int) mycard);
    }
  }  
}

数组

数组为开发人员提供了一种存储值集合的结构。除了数组之外,.NET Framework 还提供了一系列集合构造,包括哈希表和 ArrayList,它们提供了动态大小调整等功能。我们将在下一章中介绍其中一些构造。数组可以通过 foreach 构造进行处理。

using System;
namespace hks
{
  public class UseArrays
  {
    public static void Main()
    {
      String[] days_of_week = {
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday"
      };
      foreach (string day in days_of_week)
      {
        Console.WriteLine(day);
      }
    }
  }
}

变量和常量

简单值类型可以使用变量 = value 构造进行赋值,而引用类型则需要使用 new 关键字来创建新实例。

using System;
namespace hks
{
  public class UseVariables
  {
    public static void Main()
    {
      const string HELLO_WORLD = "Hello World";
      string message = HELLO_WORLD+ " in C#";
      MyClass mc = new MyClass(message);
      mc.Print();
    }
  }
  public class MyClass
  {
    private String message;
    public MyClass(String message)
    {
      this.message = message;
    }
    public void Print()
    {
      Console.WriteLine(message);
    }
  }
}

表达式

C# 中的表达式与 Java 和 C++ 编程语言提供的表达式非常相似。

using System;
namespace hks
{
  public class UseExpressions
  {
    public static void Main()
    {
      int a = 10;
      int b = 10;
      int result = a * b;
      bool check = (a == b);      
      Console.WriteLine(result);
      Console.WriteLine(check);
    }
  }
}

语句

正如预期的那样,C# 编程语言包含几个过程编程构造,包括 if-elsefor 循环、while 循环、switch 语句等。

using System;
namespace hks
{
  public class UseStatements
  {
    public static void Main()
    {
      string[] message = {"Hello", "World", "in", "C#"};
      foreach (string msg in message)
      {
        Console.Write(msg+" ");
      }
      Console.WriteLine("");
      int a = 10;
      int b = 20;
      if (a < b)
      {
        Console.WriteLine("a<b");
      }
      else
      {
        Console.WriteLine("a>=b");
      }
    }
  }
}

结构体

结构体只是值类型的聚合,分配在栈上而不是堆上。结构体对于传递一组逻辑相关的数据值很有用。结构体不支持继承但可以实现接口。例如,以下程序将打印 Hitesh.Seth,然后是 John.Doe,并说明结构体不是引用类型。

using System;
namespace hks
{
  public class UseStructures
  {
    public static void Main()
    {
      Person hs = new Person("Hitesh","Seth");
      Person jd = hs;
      jd.FirstName = "John";
      jd.LastName = "Doe";
      Console.WriteLine(hs.FirstName+"."+hs.LastName);
      Console.WriteLine(jd.FirstName+"."+jd.LastName);
    }
  }
  public struct Person
  {
    public string FirstName, LastName;
    public Person(string FirstName, string LastName)
    {
      this.FirstName = FirstName;
      this.LastName = LastName;
    }
  }
}

另一方面,类是引用类型,因此分配在堆上。类提供面向对象的构造,例如封装、多态和继承。例如,以下程序将打印 John.Doe 两次,说明对象是引用类型,分配在堆上。

using System;

namespace hks
{
  public class UseClasses
  {
    public static void Main()
    {
      Person hs = new Person("Hitesh","Seth");
      Person jd = hs;
      jd.FirstName = "John";
      jd.LastName = "Doe";
      Console.WriteLine(hs.GetFullName());
      Console.WriteLine(jd.GetFullName());
    }
  }
  public class Person
  {
    private string sFirstName, sLastName;
    public Person(string FirstName, string LastName)
    {
      this.sFirstName = FirstName;
      this.sLastName = LastName;
    }
    public string FirstName
    {
      get
      {
        return sFirstName;
      }
      set
      {
        sFirstName = value;
      }
    }
    public string LastName
    {
      get
      {
        return sLastName;
      }
      set
      {
        sLastName = value;
      }
    }
    public String GetFullName()
    {
      return this.FirstName + "."+ this.LastName;
    }
  }
}

继承

类提供继承功能,允许派生类继承基类的功能并可能覆盖某些方法。类定义包括构造函数和析构函数、成员、方法、属性和事件。(您将在本节后面了解有关事件的更多信息。)与 Java 编程语言不同,在 C# 中,所有被覆盖的方法都必须在基类中标记为 virtualis 运算符提供运行时验证对象是否为特定类型。例如,以下程序将返回 FullPerson 对象始终是 Person

using System;
namespace hks
{
  public class UseInheritance
  {
    public static void Main()
    {
      FullPerson hs = new FullPerson("Hitesh","K","Seth");
      Console.WriteLine(hs.GetFullName());
      Object oHs = hs;
      if (oHs is Person)
      {
        Console.WriteLine("I am still a Person");
      }
    }
  }
  public class Person
  {
    public string FirstName, LastName;
    public Person(string FirstName, string LastName)
    {
      this.FirstName = FirstName;
      this.LastName = LastName;
    }
    public virtual string GetFullName() {
      return this.FirstName + "." + this.LastName;
    }
  }
  public class FullPerson : Person
  {
    public string MiddleInitial;
    public FullPerson(string FirstName, string MiddleInitial, 
                    string LastName) : base(FirstName,LastName)
    {
      this.MiddleInitial = MiddleInitial;
    }
    public override string GetFullName() {
      return this.FirstName + "." + this.MiddleInitial + "." + this.LastName;
    }
  }
}

类也可以被标记为 abstract(清单 3.1),这意味着它们必须被子类化才能创建任何实例,或者 sealed,这不允许任何子类化。

清单 3.1 使用抽象类 (C#)

using System;
namespace hks
{
  public class UseAbstractClasses
  {
    public static void Main()
    {
      Person hs = new Person("Hitesh","Seth");
      Console.WriteLine(hs.GetFullName());
    }
  }
  abstract public class Abstract
  {
    protected string FirstName, LastName;
    public Abstract(string FirstName, string LastName)
    {
      this.FirstName = FirstName;
      this.LastName = LastName;
    }
    abstract public string GetFullName();
  }
  public class Person : Abstract
  {
    public Person(string FirstName, 
        string LastName) : base(FirstName, LastName)
    {    
    }
    public override string GetFullName()
    {
      return FirstName+"."+LastName;
    }
  }
}

接口

C# 提供了接口的概念。接口实际上代表了派生类需要实现的功能的签名。C# 支持接口的多重继承(清单 3.2)。

清单 3.2 使用接口 (C#)

using System;
namespace hks
{
  public class UseInterfaces
  {
    public static void Main()
    {
      Person hs = new Person();
      hs.Name = "Hitesh Seth";
      hs.Address = "1 Executive Drive, City, NJ 08520";
      Console.WriteLine(hs.GetName());
      Console.WriteLine(hs.GetAddress());
    }
  }
  public interface IName
  {
     string GetName();
  }
  public interface IAddress
  {
     string GetAddress();
  }
  public class Person : IName, IAddress
  {
    private string name, address;
    public Person()
    {
    }
    public string Name
    {
      set
      {
        name = value;
      }
    }
    public string Address
    {
      set
      {
        address = value;
      }
    }
    public string GetName()
    {
      return name;
    }
    public string GetAddress()
    {
      return address;
    }
  }
}

异常处理

C# 提供了强大的异常处理功能。例如,以下程序在运行时捕获异常,并允许向最终用户显示消息,而无需中间退出。

using System;
namespace hks
{
  public class UseExceptions
  {
    public static void Main()
    {
      try
      {
      int a = 10;
      int b = 10;
      int c = a/(a-b);
      }
      catch (Exception ex)
      {
      Console.WriteLine("Exception Caught");
      Console.WriteLine(ex.Message);
      }
    }
  }
}

也可以创建包含与底层应用程序相关的更多信息的自定义异常。自定义异常派生自 System.Exception 类。例如,清单 3.3 显示了自定义异常 TooBigDiscountException 被声明并由构造函数抛出。

清单 3.3 创建自定义异常 (C#)

using System;
namespace hks
{
  public class UseCustomExceptions
  {
    public static void Main()
    {
      try
      {
        Discount big_discount = new Discount(56);
      }
      catch (TooBigDiscountException ex)
      {
        Console.WriteLine("Exception Caught");
        Console.WriteLine(ex.Message);
      }
    }
  }
  public class Discount
  {
    private int percent;
    public Discount(int percent)
    {
      this.percent = percent;
      if (percent > 50)
        throw new TooBigDiscountException("Discount > 50%");
    }
  }
  public class TooBigDiscountException : Exception
  {
    public TooBigDiscountException(String msg) : base (msg)
    {
    }
  }
}

委托(Delegates)

委托让 C# 程序员具备函数指针的能力,基本上是将一个函数作为参数传递。例如,清单 3.4 展示了两个被创建然后调用的委托。

清单 3.4 使用委托 (C#)

using System;
namespace hks
{
  public class UseDelegates
  {
    public delegate void MyDelegate(string message);
    public static void Main()
    {
      String message = "Hello Delegates";
      MyDelegate d1 = new MyDelegate(PrintOnce);
      MyDelegate d2 = new MyDelegate(PrintTwice);
      d1(message);
      d2(message);
    }
    public static void PrintOnce(String message)
    {
      Console.WriteLine(message);
    }
    public static void PrintTwice(String message)
    {
      Console.WriteLine("1."+message);
      Console.WriteLine("2."+message);
    }
  }
}

事件

委托的典型用法是事件处理。例如,请看清单 3.5。它定义了一个名为 Button 的类,该类具有一个名为 EventHandler 的委托。可以为 OnClick 事件分配事件处理程序,并允许调用应用程序传递方法 Button_Click 的引用作为按钮被单击后调用的回调方法。在此程序中,按钮单击是通过显式调用 Click 方法完成的;在真实的 GUI 应用程序中,Click() 方法会在用户输入时自动调用。在第 7 章“使用 Windows 窗体开发 Windows 应用程序”中,您会看到代码与此应用程序非常相似。

清单 3.5 使用事件 (C#)

using System;
public class Events
{
  public static void Main()
  {
    Button button = new Button();
    button.OnClick+= new Button.EventHandler(Button_Click);
    button.Click();
  }
  public static void Button_Click()
  {
    Console.WriteLine("Button Clicked");  
  }
}
public class Button
{
  public delegate void EventHandler();
  public event EventHandler OnClick;
  public void Click()
  {
    OnClick();
  }
}

本章关于 C# 编程语言的介绍到此为止。除了本章介绍的内容之外,本书的大部分内容都以 C# 作为主要的编程语言。要进一步探索 C# 编程语言,请参阅 Steve Holzner 的《Visual C# .NET 2003 Kick Start》。

Visual Basic .NET

Visual Basic .NET 是流行的 Visual Basic 编程语言的下一个修订版,其根源在于 BASIC 编程语言本身。Visual Basic .NET 以其快速应用程序开发能力而闻名,为开发人员提供了快速开发的优势以及成熟的面向对象 (OO) 编程语言。Visual Basic .NET 建立在 Visual Basic 中现有的基本 OO 功能之上,并使该语言的面向对象特性与 Visual C# 甚至 C++ 相媲美。

凭借其易于阅读的代码语法,Visual Basic .NET 遵循以任务为导向的模型。提高开发人员生产力仍然是 Visual Basic 的核心宗旨。Visual Basic .NET 编程语言的主要特性包括:

  • 一种完全面向对象但直观的编程语言
  • 典型的 VB 功能,例如隐式类型、后期绑定、默认变量初始化和可选参数,增强的事件处理
  • 参数化属性
  • -接口成员在实现时的重新声明
  • 命令行/SDK 编译器

Hello World

以下程序列表对于现有 Visual Basic 程序员来说既熟悉又陌生。熟悉的是整体风格、子例程和模块。程序中不同的是额外的关键字——Namespace——以及 .NET Framework 类库的使用。需要牢记的重要一点是,Visual Basic .NET 不是一种区分大小写的编程语言。

Imports System
Namespace hks
  Module HelloWorld
    Public Sub Main()
      Console.WriteLine("Hello World in VB")
    End Sub
  End Module
End Namespace

Visual Basic .NET 程序以 .vb 扩展名存储。要编译 Visual Basic .NET 程序,请使用 Visual Basic. NET J# 命令行编译器 *vbc.exe*。

vbc HelloWorld.vb

利用您的 VB 技能与 Visual Basic .NET - Visual Basic .NET 编程语言的一个关键亮点是它允许开发人员利用他们在 Visual Basic 开发方面的现有技能。除了技能重用之外,Visual Basic .NET 还支持导入现有 Visual Basic 项目进行迁移。


注释

Visual Basic 注释是普通的 ' 样式行注释,或由 Rem 标识。

Imports System
Namespace hks
  Module Comments
    Rem Implement the Main Method
    Public Sub Main()
      ' Print Out Hello World
      Console.WriteLine("Hello World in VB")
    End Sub
  End Module
End Namespace

数据类型

表 3.2 描述了 Visual Basic .NET 类型如何映射到其相应的 .NET Framework 类型。

表 3.2 Visual Basic .NET 数据类型

Visual Basic .NET 类型 对应的 .NET Framework 类型
布尔值 System.Boolean
字节型 System.Byte
Char System.Char
Decimal, Double, Single System.Decimal, System.Double, System.Single
Short, Integer, Long System.Int16, System.Int32, System.Int64
对象 System.Object
字符串 System.String

枚举

Visual Basic .NET 支持枚举。清单 3.6 说明了一种潜在的用法。

清单 3.6 使用枚举 (Visual Basic .NET)

Imports System
Namespace hks
  Module UseEnumerations
    Public Enum CreditCard
      Visa
      MasterCard
      AmericanExpress
      Discover
    End Enum
    Public Sub Main()
      Dim cc as CreditCard
      cc = CreditCard.Visa
      Console.WriteLine(cc)
    End Sub
  End Module
End Namespace

数组

Visual Basic .NET 支持数组,它们是 System.Array 类型的子类(清单 3.7)。

清单 3.7 使用数组 (Visual Basic .NET)

Imports System
Namespace hks
  Module UseArrays
    Public Sub Main()
      Dim days_of_week() as String = { _
        "Sunday", _
        "Monday", _
        "Tuesday", _
        "Wednesday", _
        "Thursday", _
        "Friday", _
        "Saturday" _
      }
      Dim I as Integer
      For I = 0 to days_of_week.Length-1
        Console.WriteLine(days_of_week(I))
      Next I
    End Sub
  End Module
End Namespace

变量和常量

使用变量类似于传统的 Visual Basic 编程,使用 Dim 关键字(参见清单 3.8)。

清单 3.8 使用变量和常量 (Visual Basic .NET)

Imports System
Namespace hks
  Module UseVariables
    Public Sub Main()
      Const HELLO_WORLD as String = "Hello World"
      Dim msg as String = HELLO_WORLD & " in VB"
      Dim mc as New MClass(msg)
      Call mc.Print
    End Sub
  End Module
  Class MClass
    private message as String
    Public Sub New(ByVal message as String)
      Me.message = message
    End Sub
    Public Sub Print()
      Console.WriteLine(message)
    End Sub
  End Class
End Namespace

表达式

表达式提供了计算机化和操作数据的能力。

Imports System
Namespace hks
  Module UseExpressions
    Public Sub Main()
      Dim a as Integer = 10
      Dim b as Integer = 10
      Dim result as Integer = a * b
      Dim check as Boolean = (a = b)
      Console.WriteLine(result)
      Console.WriteLine(check)
    End Sub
  End Module
End Namespace

语句

语句提供了必要的编程语言过程构造。

Imports System
Namespace hks
  Module UseStatements
    Public Sub Main()
      Dim msg() as String = {"Hello","World","in","Visual Basic.NET"}
      Dim i as Integer
      For i = 0 to (msg.Length-1)
        Console.Write(msg(i))
      Next
      Console.WriteLine("")
      Dim a as Integer = 10
      Dim b as Integer = 20
      If (a<b) Then
        Console.WriteLine("a<b")
      Else
        Console.WriteLine("a>=b")
      End If
    End Sub
  End Module
End Namespace

结构体

结构体可用于数据的基本封装。

Imports System
Namespace hks
  Module UseStructures
    Public Sub Main()
      Dim hs as New Person("Hitesh","Seth")
      Dim jd as Person = hs
      jd.FirstName = "John"
      jd.LastName = "Doe"
      Console.WriteLine(hs.FirstName & "." & hs.LastName)
      Console.WriteLine(jd.FirstName & "." & jd.LastName)
    End Sub
  End Module
  Structure Person
    Public FirstName, LastName as String
    Public Sub New(ByVal FirstName as String, ByVal LastName as String)
      Me.FirstName = FirstName
      Me.LastName = LastName
    End Sub      
  End Structure
End Namespace

Visual Basic 中的类使用 Class 关键字定义。与 C# 类似,VB 类可以有成员、构造函数和析构函数、属性、方法(根据是否返回值分为子例程和函数)和事件(清单 3.9)。

清单 3.9 使用类 (Visual Basic .NET)

Imports System
Namespace hks
  Module Useclasses
    Public Sub Main()
      Dim hs as New Person("Hitesh","Seth")
      Dim jd as Person = hs
      jd.FirstName = "John"
      jd.LastName = "Doe"
      Console.WriteLine(hs.FirstName & "." & hs.LastName)
      Console.WriteLine(jd.FirstName & "." & jd.LastName)
    End Sub
  End Module
  Public Class Person
    Private sFirstName, sLastName as String
    Public Property FirstName() as String
      Get
        Return sFirstName
      End Get
      Set(ByVal Value as String)
        sFirstName = Value
      End Set
    End Property
    Public Property LastName() as String
      Get
        Return sLastName
      End Get
      Set(ByVal Value as String)
        sLastName = Value
      End Set
    End Property
    Public Sub New(ByVal FirstName as String, ByVal LastName as String)
      Me.FirstName = FirstName
      Me.LastName = LastName
    End Sub
    Public Function GetFullName() as String
      Return Me.FirstName & "." & Me.LastName
    End Function    
  End Class
End Namespace

类可以被继承,以覆盖和扩展基类中存在的功能。OverridableOverrides 关键字分别用于将基类中的方法设置为可重写,以及在派生类中实现重写方法(清单 3.10)。与 C# 类似,Visual Basic .NET 也仅支持单继承。

清单 3.10 使用继承 (Visual Basic .NET)

Imports System
Namespace hks
  Module HelloWorld
    Public Sub Main()
      Dim hs as New FullPerson("Hitesh","K","Seth")
      Console.WriteLine(hs.GetFullName)
    End Sub
  End Module
  Public Class Person
    Public FirstName, LastName as String
    Public Sub New(ByVal FirstName as String, ByVal LastName as String)
      Me.FirstName = FirstName
      Me.LastName = LastName
    End Sub      
    Public Overridable Function GetFullName() as String
      Return Me.FirstName & "." & Me.LastName
    End Function
  End Class
  Public Class FullPerson
    Inherits Person
    Public MiddleInitial as String
    Public Sub New(ByVal FirstName as String, _ 
        ByVal MiddleInitial as String, ByVal LastName as String)
      MyBase.New(FirstName,LastName)
      Me.MiddleInitial = MiddleInitial
    End Sub
    Public Overrides Function GetFullName() as String
      Return Me.FirstName & "." & Me.MiddleInitial & "." & Me.LastName
    End Function
  End Class
End Namespace

Visual Basic .NET 通过使用 MustInheritMustOverride 关键字支持抽象类(清单 3.11)。

清单 3.11 使用抽象类 (Visual Basic .NET)

Imports System
Namespace hks
  Module UseAbstractClasses
    Public Sub Main()
      Dim hs as New Person("Hitesh","Seth")
      Console.WriteLine(hs.FirstName & "." & hs.LastName)
    End Sub
  End Module
  Public MustInherit Class Abstract
    Public FirstName, LastName as String
    Public Sub New(ByVal FirstName as String, ByVal LastName as String)
      Me.FirstName = FirstName
      Me.LastName = LastName
    End Sub  
    Public MustOverride Function GetFullName as String  
  End Class
  Public Class Person
    Inherits Abstract
    Public Sub New(ByVal FirstName as String, ByVal LastName as String)
      MyBase.New(FirstName,LastName)
    End Sub
    Public Overrides Function GetFullName as String
      GetFullName = FirstName & "." & LastName
    End Function
  End Class
End Namespace

接口

Visual Basic .NET 通过 Interface 关键字支持接口。派生类可以实现多个接口,并通过 Interface 关键字指定实现的特定函数/子例程签名(清单 3.12)。

清单 3.12 使用接口 (Visual Basic .NET)

Imports System
Namespace hks
  Module UseInterfaces
    Public Sub Main()
      Dim hs as New Person
      hs.Name = "Hitesh Seth"
      hs.Address = "1 Executive Drive, City, NJ 08520"
      Console.WriteLine(hs.GetName())
      Console.WriteLine(hs.GetAddress())
    End Sub
  End Module
  Public Interface IName
    Function GetName() as String    
  End Interface
  Public Interface IAddress
    Function GetAddress() as String    
  End Interface
  Public Class Person
    Implements IName, IAddress
    Private s_name, s_address as String
    Public Sub New()
    End Sub
    Public WriteOnly Property Name() as String
      Set
        s_name = value
      End Set
    End Property
    Public WriteOnly Property Address() as String
      Set
        s_address = value
      End Set
    End Property
    Public Function GetName() as String Implements IName.GetName
      GetName = s_name
    End Function
    Public Function GetAddress() as String Implements IAddress.GetAddress
      GetAddress = s_address
    End Function
  End Class
End Namespace

异常处理

Visual Basic .NET 新增了结构化异常处理,如清单 3.13 所示。Visual Basic 通常使用 OnError/Goto 构造来处理异常。

清单 3.13 异常处理 (Visual Basic .NET)

Imports System
Namespace hks
  Module UseExceptions
    Public Sub Main()
      Try
        Dim a as Integer = 10
        Dim b as Integer = 10
        Dim c as Integer
        c = a/(a-b)
      Catch ex as Exception
        Console.WriteLine(ex.Message)
      End Try
    End Sub
  End Module
End Namespace
Imports System

与 C# 类似,除了处理 .NET Framework 库定义的广泛异常集之外,还可以通过子类化 Exception 类来定义自定义异常(清单 3.14)。

清单 3.14 创建自定义异常 (Visual Basic .NET)

Namespace hks
  Module UseCustomExceptions
    Public Sub Main()
      Try
        Dim big_discount as new Discount(56)
      Catch ex as Exception
        Console.WriteLine(ex.Message)
      End Try
    End Sub
  End Module
  Public Class Discount
    Private percent as Integer
    Public Sub New(ByVal percent as Integer)
      Me.percent = percent
      If (percent > 50) Then
        Throw New TooBigDiscountException("Discount > 50%")
      End If
    End Sub
  End Class
  Public Class TooBigDiscountException
    Inherits Exception
    Public Sub New(ByVal msg as String)
      MyBase.New(msg)
    End Sub
  End Class
End Namespace

委托(Delegates)

Visual Basic .NET 新增了使用委托或函数指针的能力(清单 3.15)。

清单 3.15 使用委托 (Visual Basic .NET)

Imports System
Namespace hks
  Module Use Delegates
    Delegate Sub MyDelegate(ByVal msg as String)
    Public Sub Main()
      Dim msg As String = "Hello Delegates"
      Dim d1 as MyDelegate = AddressOf PrintOnce
      Dim d2 as MyDelegate = AddressOf PrintTwice
      d1(msg)
      d2(msg)
    End Sub
    Public Sub PrintOnce(ByVal msg as String)
      Console.WriteLine(msg)
    End Sub
    Public Sub PrintTwice(ByVal msg as String)
      Console.WriteLine("1." & msg)
      Console.WriteLine("2." & msg)
    End Sub
  End Module
End Namespace

事件

Visual Basic 开发人员传统上一直享受到易于使用的事件处理系统的好处(清单 3.16)。

清单 3.16 使用事件 (Visual Basic .NET)

Imports System
Namespace hks
  Module Events
    Friend WithEvents button As Button
    Public Sub Main()
      button = New Button()
      button.Click
    End Sub
    Public Sub Button_OnClick Handles button.OnClick
      Console.WriteLine("Button Clicked")
    End Sub
  End Module
  Public Class Button
    Public Event OnClick
    Public Sub Click()
      RaiseEvent OnClick()
    End Sub
  End Class
End Namespace

Visual J#

通过 Visual Studio,微软推出了 Visual J++ 编程语言和开发工具。Visual J++ 在 Microsoft Windows 平台上提供了基于 Java 的应用程序开发。用 Visual J++ 开发的程序和组件在 Microsoft Java 虚拟机上执行。然而,Visual J# 则大不相同,因为它允许基于 Java 的程序使用 MSIL 编译成 .NET 组件和应用程序。因此,J# 编程语言实际上与 C# 或 Visual Basic .NET 类似,但编程语言语法是 Java 编程语言的语法。J# 仍然具有 Java 编程语言的所有优点,作为一种简化的面向对象编程语言(无指针等)。它基于 JDK 1.1.4。


为什么选择 J#? - 微软推出 J# 是为了利用全球 Java 开发人员的大量技能储备,并为他们提供利用现有技能和语言经验开发 .NET 应用程序的能力。


使用 Visual J# 编程语言,现有 Java 开发人员可以执行以下操作:

  • 利用 Java 编程知识进行 .NET 应用程序开发
  • 支持 JDK 1.1.4 类库和大多数 JDK 1.2 java.util 类库
  • 利用 Java 编程语言的扩展功能,包括属性、委托和事件
  • 使用项目导入向导将现有 Visual J++ 项目转换为 Visual J#
  • 创建基于 Javadoc 的文档
  • 支持 applet,如部署模型,称为 J# 浏览器控件

Hello World

一个简单的 Hello World J# 应用程序看起来很像一个典型的 Java 应用程序。唯一的区别是使用了 .NET Framework 类库 (System.Console.WriteLine) 而不是典型的 Java System.out.println。Java 通过包支持命名空间的概念,这已被纳入 J# 的 .NET 命名空间。此外,Java 提供了使用 import 关键字使用外部类库的功能。这也已在 J# 中使用。(注意:J# 要求命名空间后面附加“.*”。)

package hks;
import System.*;
public class HelloWorld
{
  public static void main()
  {
    Console.WriteLine("Hello World in J#");
  }
}

J# 程序以 .jsl 扩展名存储。要编译 J# 应用程序,请使用 .NET J# 编译器 *vjc.exe*。

vjc HelloWorld.jsl

注释

除了与 C# 相似的单行和多行注释外,J# 还支持并扩展了传统的 Javadoc 风格注释。(对于非 Java 程序员,Javadoc 风格注释是类似于 C# 中 XML 注释的特殊注释,用于自动从 Java 程序生成 HTML 文档。)

package hks;
import System.*;
public class Comments
{

  public static void main()
  {
    // A Simple Comment
    /*
      A multi
      line comment
    */
    Console.WriteLine("Hello World in J#");
  }
}

数据类型

表 3.3 显示了 Visual J# 类型如何映射到相应的 .NET Framework 类型。

表 3.3 Visual J# 数据类型

Visual J# 类型 对应的 .NET Framework 类型
布尔值 System.Boolean
byte System.Byte, System.SByte
char System.Char
double, float System.Double, System.Single
short, int, long System.Int16, System.Int32, System.Int64
对象 System.Object
字符串 System.String

枚举

J# 不支持创建枚举。但是,该语言确实提供了使用已在 .NET Framework 或任何自定义 .NET 程序集中定义的枚举的能力。枚举也被视为引用类型。

数组

如以下程序所示,使用数组与 C# 非常相似。请注意用于获取数组长度的 get_Length() 方法,因为 J# 不支持属性。

package hks;
import System.*;
public class UseArrays
{
  public static void main()
  {
    String[] days_of_week = {
      "Sunday",
      "Monday",
      "Tuesday",
      "Wednesday",
      "Thursday",
      "Friday",
      "Saturday"
    };
    for (int i=0;i<days_of_week.get_Length();i++)
    {
      Console.WriteLine(days_of_week[i]);
    }
  }
}

变量和常量

J# 中的常量以 final 关键字为前缀。所有其他创建新值类型和引用类型的机制都与 C# 类似。

package hks;
import System.*;
public class UseVariables
{
  public static void main()
  {
    final String HELLO_WORLD = "Hello World";
    String message = HELLO_WORLD + " in VJ#";
    MyClass mc = new MyClass(message);
    mc.Print();
  }
}
public class MyClass
{
  private String message;
  public MyClass(String message)
  {
    this.message = message;
  }
  public void Print()
  {
    Console.WriteLine(message);
  }
}

表达式

J# 中的基本表达式与 C# 中的非常相似。

package hks;
import System.*;
public class UseExpressions
{
  public static void main()
  {
    int a = 10;
    int b = 10;
    int result = a*10;
    boolean check = (a==b);
    Console.WriteLine(result);
    Console.WriteLine(check);
  }
}

语句

J# 中的语句与 C# 中的非常相似。

package hks;
import System.*;
public class UseStatements
{
  public static void main()
  {
    String[] message = {"Hello","World","in","VJ#"};
    for (int i=0;i<message.get_Length();i++)
    {
      Console.Write(message[i]+" ");
    }
    int a = 10;
    int b = 10;
    if (a<b) {
      Console.WriteLine("a<b");
    } else {

      Console.WriteLine("a>=b");
    }
  }
}

J# 中的类定义、抽象类、继承等构造与 C# 中的非常相似(清单 3.17)。但是,Java 编程语言中不支持属性;J# 也沿袭了这一点。但 J# 通过属性访问器方法(set_get_)支持属性。

清单 3.17 使用类 (Visual J#)

package hks;
import System.*;
public class Useclasses
{
  public static void main()
  {
    Person hs = new Person("Hitesh","Seth");
    Person jd = hs;
    jd.set_FirstName("John");
    jd.set_LastName("Doe");
    Console.WriteLine(hs.GetFullName());
  }
}
public class Person
{
  private String sFirstName, sLastName;
  public Person(String FirstName, String LastName)
  {
    this.sFirstName = FirstName;
    this.sLastName = LastName;
  }
  public void set_FirstName(String FirstName) {
    this.sFirstName = FirstName;
  }
  public String get_FirstName()
  {
    return sFirstName;
  }
  public void set_LastName(String LastName) {
    this.sLastName = LastName;
  }
  public String get_LastName()
  {
    return sLastName;
  }
  public String GetFullName() {
    return sFirstName +"."+sLastName;
  }
}

与 C# 类似,J# 也支持单继承,包括重写基类方法(清单 3.18)。然而,与 C# 不同的是,所有非私有方法都可以被派生类重写。因此,本质上,J# 方法的行为类似于虚方法。

清单 3.18 继承类 (Visual J#)

package hks;
import System.*;
public class UseInheritance
{
  public static void main()
  {
    FullPerson hs = new FullPerson("Hitesh","K","Seth");
    Console.WriteLine(hs.GetFullName());
    Object oHs = hs;
    if (oHs instanceof Person)
    {
      Console.WriteLine("I am still a Person");
    }
  }
}
public class Person
{
  public String FirstName, LastName;
  public Person(String FirstName, String LastName)
  {
    this.FirstName = FirstName;
    this.LastName = LastName;
  }
  public String GetFullName() {
    return FirstName + "." + LastName;
  }
}
public class FullPerson extends Person
{
  public String MiddleInitial;
  public FullPerson(String FirstName, String MiddleInitial, String LastName)
  {
    super(FirstName,LastName);
    this.MiddleInitial = MiddleInitial;
  }
  public String GetFullName() {
    return FirstName + "." + MiddleInitial + "." + LastName;
  }
}

抽象类的支持方式与 C# 类似(清单 3.19)。

清单 3.19 使用类 (Visual J#)

package hks;
import System.*;
public class UseAbstractClasses
{
  public static void main()
  {
    Person hs = new Person("Hitesh","Seth");
    Console.WriteLine(hs.GetFullName());
  }
}
public abstract class Abstract
{
  protected String FirstName, LastName;
  public Abstract(String FirstName, String LastName)
  {
    this.FirstName = FirstName;
    this.LastName = LastName;
  }
  abstract public String GetFullName();
}
public class Person extends Abstract
{
  public Person(String FirstName, String LastName)
  {    
    super(FirstName, LastName);
  }
  public String GetFullName()
  {
    return FirstName+"."+LastName;
  }
}

接口

凭借与 C# 非常相似的构造,J# 编程语言也支持使用接口的多重继承(清单 3.20)。实际上,简单的接口机制在某种意义上是由 Java 引入并被 C# 采用的。

清单 3.20 使用接口 (Visual J#)

package hks;
import System.*;
public class UseInterfaces
{
  public static void main()
  {
    Person hs = new Person();
    hs.set_Name("Hitesh Seth");
    hs.set_Address("1 Executive Driver, City, NJ 08520");
    Console.WriteLine(hs.GetName());
    Console.WriteLine(hs.GetAddress());
  }
}
public interface IName
{
   public String GetName();
}
public interface IAddress
{
  public String GetAddress();
}
public class Person implements IName, IAddress
{
  private String name, address;
  public Person()
  {
  }
  public void set_Name(String value)
  {
    name = value;
  }
  public void set_Address(String value)
  {
    address = value;
  }
  public String GetName()
  {
    return name;
  }
  public String GetAddress()
  {
    return address;
  }
}

异常处理

异常处理在 Java 编程语言中一直受到支持,这种能力也可以很容易地与 .NET 异常模型一起重用。

package hks;
import System.*;
public class UseExceptions
{
  public static void main()
  {
    try
    {
    int a = 10;
    int b = 10;
    int c = a/(a-b);
    }
    catch (System.Exception ex)
    {
    Console.WriteLine("Exception Caught");
    Console.WriteLine(ex.get_Message());
   }
  }
}

J# 支持自定义异常,这与 C# 非常相似(清单 3.21)。

清单 3.21 创建自定义异常 (Visual J#)

package hks;
import System.*;
public class UseCustomExceptions
{
  public static void main()
  {
    try
    {
      Discount big_discount = new Discount(56);
    }
    catch (TooBigDiscountException ex)
    {
      Console.WriteLine("Exception Caught");
      Console.WriteLine(ex.get_Message());
    }
  }
}
public class Discount
{
  private int percent;
  public Discount(int percent) throws TooBigDiscountException
  {
    this.percent = percent;
    if (percent > 50)
      throw new TooBigDiscountException("Discount > 50%");
  }
}
public class TooBigDiscountException extends System.Exception
{
  public TooBigDiscountException(String msg)
  {
      super(msg);
  }
}

委托和事件

由于 Java 编程语言没有内置的委托和事件支持,J# 实现提供了一组扩展来创建此功能。委托在定义之前用特殊注释 /** @delgate */ 标记,事件也是如此(使用 /** @event */)。此外,实现事件的类需要通过创建 ArrayList 或类似集合来保留分配给特定事件的所有侦听器的引用。分配侦听器后,使用 Invoke 方法调用它们(清单 3.22)。

清单 3.22 使用委托和事件 (Visual J#)

package hks;
import System.*;
import System.Collections.*;

/** @delegate */
public delegate void EventHandler();

public class Button
{
  ArrayList listeners = new ArrayList();
  public static void main()
  {
    Button button = new Button();
    button.add_OnClick(new EventHandler(Button_OnClick));
    button.Click();
  }
  /** @event */
  public void add_OnClick(EventHandler listener) {
    listeners.Add(listener);
  }
  /** @event */
  public void remove_OnClick(EventHandler listener) {
    listeners.Remove(listener);
  }
  public void Click()
    {
     Object [] olisteners = listeners.ToArray();
    for (int i = 0;i < olisteners.length ;i++)
       {
         ((EventHandler)(olisteners[i])).Invoke();
       }
    }
  public static void Button_OnClick()
  {
    Console.WriteLine("Button Clicked");
  }
}

托管 C++

托管 C++ 并非真正代表一种独立的编程语言。 .NET Framework 引入的一些功能并未通过标准 C++ 编程语言 Visual C++ 2003(也称为托管 C++)得到支持。托管 C++ 扩展代表了一组额外的关键字,它们为 C++ 提供了开发 .NET 构造所需的扩展。

Visual C++ .NET 被称为面向力量的编程语言,它为 .NET 应用程序开发人员提供了力量、控制和以性能为中心的本机代码和托管代码环境桥接的终极组合。Visual C++ .NET 编程语言的主要亮点包括:

  • 同时利用 Win32/本地 Windows 和 CLR 环境
  • 持续支持标准 ISO C++,实现跨 C++ 实现环境的可移植性
  • 支持高级 C++ 功能,如模板、指针和内部功能(如特定于处理器的指令)
  • 支持 32/64 位微处理器的高优化编译器
  • 高级错误报告和调试

Hello World

#using <mscorlib.dll>
using namespace System;
void main()
{
  Console::WriteLine(S"Hello World in Managed C++");
}

编译启用托管扩展的 C++ 程序需要使用 /CLR 编译器选项,这表明编译器必须将 C++ 程序编译成 .NET 程序集。

cl /CLR HelloWorld.cpp

托管扩展

表 3.4 提供了 C++ 编程语言中主要托管扩展的快速列表。

表 3.4 主要托管 C++ 扩展关键字

托管 C++ 扩展 描述
__gc 表示所标识的结构/类是托管的(垃圾回收)
__value 表示值类型
__interface 接口
__delegate 委托(Delegates)
__event 事件
__property 属性
__abstract 抽象类:必须派生才能创建实例
__sealed 密封(最终)类:不能派生
__identifier 使用 C++ 关键字作为标识符
__typeof 提供对对象类型的访问
__try_cast 提供动态检查的转换

要创建一个托管类(这意味着不需要分配),请在 C++ 类定义前加上 __gc 关键字。这表示告诉 C++ 编译器将要声明的是一个托管 C++ 类(清单 3.23)。

清单 3.23 创建托管类 (Managed C++)

#using <mscorlib.dll>
namespace hks {
 __gc class Person
 {
  public:
    System::String* FirstName;
    System::String* LastName;
    Person(System::String* FirstName, System::String* LastName)
    {
      this->FirstName = FirstName;
      this->LastName = LastName;
    }
 };
};
void main()
{
  hks::Person* p1 = new hks::Person(S"Hitesh",S"Seth");
  hks::Person* p2 = p1;
  p1->FirstName = S"John";
  p2->LastName = S"Doe";
  System::Console::WriteLine("{0}.{1}",p1->FirstName,p1->LastName);
  System::Console::WriteLine("{0}.{1}",p2->FirstName,p2->LastName);

}

清单 3.24 是另一个使用托管扩展的示例,这次是创建事件和委托。

清单 3.24 使用事件和委托托管扩展 (Managed C++)

#using <mscorlib.dll>
namespace hks {
 __delegate void MyDelegate(System::String *msg);
 __gc class HelloWorld
 {
  public:
    void PrintOnce(System::String *msg)
    {
      System::Console::WriteLine(msg);
    }
    void PrintTwice(System::String *msg)
    {
      System::Console::WriteLine("1.{0}",msg);
      System::Console::WriteLine("2.{0}",msg);
    }
 };
};
int main()
{
  hks::HelloWorld* hw = new hks::HelloWorld();
  System::String *msg = S"Hello Delegates";
  hks::MyDelegate *d1 = new hks::MyDelegate(hw,&hks::HelloWorld::PrintOnce);
  hks::MyDelegate *d2 = new hks::MyDelegate(hw,&hks::HelloWorld::PrintTwice);
  d1->Invoke(msg);
  d2->Invoke(msg);
}

其他 .NET 编程语言

如果您认为支持四种编程语言(C#、Visual Basic .NET、C++ 和 J#)使得 .NET 编程具有灵活性,那么您还没有完全理解。由于每个程序最终都将以 MSIL 形式存在,然后由 CLR 执行,因此实际上可以为任何编程语言编写编译器,无论是它支持面向对象构造、函数式编程构造、模块化编程构造,还是纯粹的过程式构造,以便它可以编译成 MSIL。这是 .NET 广泛的第三方编程语言支持背后的驱动力。如果您了解一种编程语言,很可能它已经被移植到 .NET。这包括 APL、COBOL、Delphi、Eiffel、Fortran、Forth、Haskell、Prolog、Pascal、Perl、Python、Scheme 等。正如您所看到的,CLR 允许开发人员利用他们所掌握的任何编程语言的技能,并将其应用于 .NET 环境。将 COBOL 技能应用于 .NET 意味着您可以使用 COBOL 开发丰富的 Windows 窗体应用程序、Web 应用程序,甚至 Web 服务。这些是这些语言最初设计时从未想过的编程构造。正是由于 CLR 的丰富性和灵活性,才使这样的事情成为可能。

微软研究院在设计和实现 .NET 新编程语言方面一直非常活跃。ASML(抽象状态机语言)、F#(Caml 编程语言的一个实现)和 SML.NET(Standard ML 的一个实现)是微软研究院探索 .NET 新编程模型的一些举措。

语言来来去去;第三代编程语言将演变为第四代编程语言,依此类推。有了 CLR,.NET 编程模型将随着这种变化而演进,并利用计算机科学界的技术卓越和研究成果。

.NET 编程语言的更新列表可在 http://www.jasonbock.net/dotnetlanguages.html 找到。

不同编程语言之间的互操作

本节的目的是为了说明 .NET *确实*支持跨编程语言使用。您将学习如何在一个编程语言中定义的类可以在另一个编程语言中被子类化,并在另一个编程语言中被使用。首先,在 C# 中定义 Base 类。

using System;
namespace mixed
{
 public class Base
 {
  public Base()
  {    
  }
  public virtual String GetLanguage()
  {
    return "C#";
  }
 }
}

此程序使用 C# 编译器编译成一个库。

csc /t:library CSharp.cs

接下来,声明一个 Visual Basic .NET 类作为 Base 类的子类。

Imports System
Namespace mixed
  Public class Derived
    Inherits Base
    Public Sub New()
    End Sub
    Public Overrides Function GetLanguage() As String
      return "Visual Basic .NET"
    End Function
  End Class
End Namespace

要编译 Visual Basic 程序,调用 Visual Basic .NET 编译器,并传递对先前创建的基类程序集的引用。

vbc /reference:CSharp.dll /target:library VBasic.vb

现在,您最终将开发一个实际使用前面定义的类的 Java 类。该 Java 类有一个 main 方法,因此可以编译成一个可执行文件。

vjc /reference:CSharp.dll,VBasic.dll VJSharp.jsl

程序 *VJSharp.exe* 可以执行以获得结果

Visual Basic .NET
Derived is an instance of Base

这个小练习应该消除关于各种编程语言的 .NET 互操作性的任何疑虑。


选择正确的编程语言 - .NET 编程模型为开发人员在选择编程语言实现应用程序或创建组件库时提供了真正的选择。选择使用的语言主要取决于您现有的技能,是您的个人选择。如果您是 Visual Basic 程序员,您可能会选择 Visual Basic .NET。如果您是 C++ 程序员,您将继续使用 Visual C++ .NET 或考虑 C# 作为您的主要编程语言。如果您有 Java 编程背景,您最终可能会选择 Visual J# 或 Visual C#。影响编程语言选择的另一个因素是您所在地区的普遍性和市场需求。例如,目前纽约市大都市区(我居住的地方)似乎正朝着 C# 的方向发展,这基于其强大的 C++ 影响力。尽管在单个解决方案中混合不同的编程语言绝对是可能的,但在我看来,这种情况很少发生。在许多方面,可以使用不同的编程语言来实现相似的结果;有时语言的选择受到所编写应用程序类型的影响。例如,Perl 可能是用于大量 .NET 组件的绝佳选择,这些组件执行复杂的模式匹配和文本处理。简而言之,当您选择编程语言时,您应该考虑您现有的技能,并将它们与不同语言提供的编程构造相结合,从而做出明智的决定。


简而言之

  • .NET Framework 编程模型为开发人员在为 .NET 应用程序、Web 服务或组件选择编程语言时提供了真正的选择。
  • C#、Visual Basic、C++ 和 J# 是 .NET 的四种主要编程语言,至少是开箱即用,带有 Framework 和 Visual Studio .NET 工具。
  • C# 代表着最现代、最前沿、最具创新性的编程语言,而 Visual Basic .NET 则代表着高易用性和开发人员生产力。C++ 为 .NET 开发人员提供了强大的功能,特别是在底层操作系统、Win32 API 访问以及与现有应用程序和组件最高效的互操作性方面。J# 为 Java 开发人员提供了轻松进入 .NET 编程模型的途径。
  • 许多 ISV 已将各种编程语言移植到 CLR 的输出 MSIL。
  • 选择正确的编程语言主要取决于您现有的技能和用途。例如,C++ 将是与 Windows 操作系统 API 和现有应用程序高效互操作的首选语言。
© . All rights reserved.