感受.net的跨語言特性
這段時間學習.net,在網上也找了很多的資料,發現大多的教程都在討論著.net的技術趨勢和給軟件生產帶來的變化.常常是簡單說說.象分布計算呀,組件化呀等等,卻很少有這方面的稍稍感性點的認識.對于高手來說或許這樣的介紹已經是足夠的了.可對于大量象我這樣的初學者,其實很難能理解那分布計算.那組件化的到底代表著什么,唯一能知道的就是那是很高深的技術.
于是乎自己有了個不自量力的想法.把自己看過的東西寫出來,希望能對象我這樣的菜鳥對c#或者說是.net有點感性的認識,同時也讓大家來批批,幫助自己進步.
.net 支持語言無關,和語言集成,你可以繼承一種符合.net 公用類型系統(CTS)的語言寫的類,捕獲他的異常,使用跨語言的多太性.也就是說在.net環境下各種語言是可以混合使用的.你可以從完全不同的語言寫成的基類派生一個類,也可以在程序里捕獲用另一種語言編寫的異常等等.
在本例中,我們將使用受管制的c++生成一個抽象基類human;
然后用vb.net生成一個從human派生的類woman,用c#生成一個從human派生的類man.
其結構如下:
用c++寫的抽象基類:Human
他有三個多態方法:EatFood(),Sport(),ErrorSomething()
用vb.net寫的Human派生類:Woman
他將覆蓋Human的三個方法EatFood(),Sport(),ErrorSomething()
并將在ErrorSomething()中拋出一個異常
用c#寫的Human派生類:Man
他將覆蓋Human的三個方法EatFood(),Sport(),ErrorSomething()
我們使用受管制的c++來寫寫基類human,它實現了一個Iface接口,以支持吃東西和運動,同時有個叫ErrorSomething的虛函數,任何Human的具體繼承類都必須實現這個方法.
代碼如下
---------code start ------------
//文件名字:human.cpp
#using <mscorlib.dll>
using namespace System;
public __gc __interface Iface
{
void EatFood();
void Sport();
};
public __gc class Human:public Iface
{
public:
virtual void EatFood()
{
Console::WriteLine("是人都得吃東西!");
}
virtual void Sport()
{
Console::WriteLine("生命在于運動!");
}
virtual void ErrorSomething()=0;
};
--------------code end---------------
同時保存該定義到human.dll文件中
使用下面命令編譯和連接
cl /CLR /c human.cpp
link -dll /out:human.dll -noentry human.obj
我們將使用vb.net從Human的基類中派聲出一個叫Woman的類,在這里我們將覆蓋EatFood(),Sport()和ErrorSomething三個方法,在這里ErrorSomething有點特殊,我們將在該方法中人工拋出一個異常,以測試當使用其他語言繼承用vb.net寫的該類后能不能捕獲這個異常.
代碼如下
---------------------code start--------------------
'文件名字:woman.vb
Imports System
Public Class Woman
Inherits Human
Overrides Public Sub EatFood()
Console.WriteLine("女性吃的東西")
End Sub
Overrides Public Sub Sport()
Console.WriteLine("女性運動")
End Sub
Overrides Public Sub ErrorSomething()
Console.WriteLine("女性類發生錯誤")
throw new Exception("異常拋出")
End Sub
End Class
--------------------code end-----------------------------
使用vb.net編譯器生成dll
vbc /r:human.dll /t:library /out:woman.dll woman.vb
現在我們用c#生成從Human繼承來的第二個類Man,和用vb.net生成的Woman類相似,這里同樣將覆蓋三個虛函數,但在ErrorSomething()方法中不拋出異常.
---------code start-----------------
//文件名: man.cs
using System;
public class Man:Human
{
override public void EatFood()
{
Console.WriteLine("男性吃的東西");
}
override public void Sport()
{
Console.WriteLine("男性運動");
}
override public void ErrorSomething()
{
Console.WriteLine("男性發生錯誤");
}
}
--------------code end--------------
使用如下命令生成dll
csc /r:human.dll /t:library /out:man.dll man.cs
最后讓我們生成一個測試類,以測試跨語言應用多態性和異常處理
以下代碼使用c#包含一個Main()方法,帶有一個Human應用和一個異常處理器.
--------------code start-------------------------
//文件名:test.cs
using System;
class Test
{
public static void Main()
{
Human hh;
try
{
Man mm=new Man();
hh=mm;
hh.EatFood();
hh.ErrorSomething();
Woman ww=new Woman();
hh=ww;
hh.EatFood();
hh.ErrorSomething();
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
--------------code end------------------------
在Test類中有個Main()方法.首先定義了一個來自Human類的對象hh,在try語句中先實例化了一個Man類,并用hh引用指向它.這里我們沒有讓Man去執行EatFood(),或者ErrorSomething(),而是讓一個Human對象hh去做,同樣實例化一個Woman類,用hh引用指向他,也不讓Woman類去執行EatFood()或者ErrorSomething(),而是讓Human對象去做.表面上看是Human執行EatFood()和ErrorSomething(),但實際上前者是Man是實例,后者是Woman實例.也就是多態性,不過他是跨語言的
同時在第二個ErrorSomething中因為是個Woman類,它拋出了個異常,我們將在Test類中捕獲這個異常,由于異常的拋出那段程序是用vb.net寫的,而我們捕獲異常是在c#中,這也就說明了異常的處理同樣是可以跨語言的.
通過以下命令創建一個exe文件
csc /r:human.dll;woman.dll;man.dll /t:exe /out:test.exe test.cs
其各部分編譯和最后運行結果如下圖:
原文轉自:http://www.anti-gravitydesign.com