C#中的函式指標 (轉)

amyz發表於2007-08-16
C#中的函式指標 (轉)[@more@]

指標也叫指向函式的指標,它是為了提高函式的通用性而引入的。比較傳統的方法是在函式中增加引數,透過增加的引數來判斷到底要用什麼函式,這樣的缺點是靈活性差,為了支援多種方法要在函式中要寫很多分支判斷語句。比如,你要計算一個函式值(如sin x,log10 x)的平方,按照傳統的方法你可以這樣寫這個函式:


public double Fuction(double Param,int Functionion)
{
 if(FunctionSelection=0)
 return Math.Pow(Math.Sin(Param),2);
 if(FunctionSelection=1)
 return Math.Pow(Math.Log10(Param),2);
 .............. 
}


顯然,這種方法很費事,造成函式體很長。所以,函式指標的思想很重要。大家可能很熟悉C++中的DDP函式指標型別,那麼,在完全面向的語言中函式指標是什麼樣子的呢?

在C#中我們使用delegate(委託)關鍵字來實現函式指標。
在《 Essential》中有一個經典的例子:

using System;
namespace testDelegate
{
public class testDelegate
{
//1.定義回撥函式指標.
delegate void MsgHandler(string strMsg);
//2.定義回撥函式.
void OnMsg(string strMsg)
{
Console.WriteLine(strMsg);
}
public static void Main()
{
testDelegate t=new testDelegate();
//3.連線函式指標物件f到t.OnMsg.
MsgHandler f=new MsgHandler(t.OnMsg);
//4.指標的回撥函式
f("Hello,Delegate!");
}
}
}

上面的例子註釋說明了實現函式指標所要做的工作,我們發現在delegate void MsgHandler(string strMsg)一句中的引數是字串型的,說明能夠指向的函式也必須只有一個字串引數,而MsgHandler f=new MsgHandler(t.OnMsg);中是把t.OnMsg這個函式直接傳遞給f。這個例子過於簡單,但是已經說明函式指標的用法。我們不妨解決一下前面提出的計算不同函式值的平方的問題。

首先定義一個函式委託(指標):

delegate double DoubleHandler(double D_Parm);

這相當於在C++定義函式指標型別。

第二步定義回撥函式就免了,因為我們可以使用Math.Sin函式和Math.Log10函式,但是我們必須定義一個函式來求平方:

public static double MathMethod(double parm1)
{
 return Math.Pow(parm1,2);
}

這個函式和前面那個加引數的函式相比簡單多了,但更具有通用性。

下面要做的就是要給前面定義的函式指標型別(即函式委託)建立物件並對其用函式將它初始化了:

DoubleHandler DoubleMethod=new DoubleHandler(Math.Sin);

大家已經看到了,這個指標指向了Math.Sin函式,相當於C++中的完成了對函式指標型別的“賦值”(初始化)。大家也可以透過新增DoubleMethod=new DoubleHandler(Math.Log10);重新初始化來改變函式指標的指向的函式物件。

最後就是計算函式值的平方了:

double d=MathMethod(DoubleMethod(.5);

以下是完整的,在.NET 下透過:

using System;

namespace testDelegate
{
 public class testDelegate
 {
 delegate void MsgHandler(string strMsg);
 delegate double DoubleHandler(double D_Parm);

 void OnMsg(string strMsg)
 {
 Console.WriteLine("The result is: {0}",strMsg);
 }

 public static double MathMethod(double parm1)
 {
 return Math.Pow(parm1,2);
 }

 public static void Main()
 {
 testDelegate t=new testDelegate();
 MsgHandler f=new MsgHandler(t.OnMsg);

 DoubleHandler[] DoubleMethod={
 new DoubleHandler(Math.Sin),
 new DoubleHandler(Math.Log10),
 new DoubleHandler(Math.Sqrt)
 };
 foreach(DoubleHandler handle in DoubleMethod)
 {
 f(MathMethod(handle(.5)).ToString()); //呼叫MsgHandler的物件f來顯示計算結果
 }
 }
 }
}

上面的例子很能說明問題,有意識的使用C# delegate實現函式指標,能夠有效的簡化程式碼,提高函式的通用性。 (完)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-962438/,如需轉載,請註明出處,否則將追究法律責任。

相關文章