`
javasogo
  • 浏览: 1844085 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

C#中的函数指针

阅读更多

函数指针也叫指向函数的指针,它是为了提高函数的通用性而引入的。比较传统的方法是在函数中增加参数,通过增加的参数来判断到底要用什么函数,这样的缺点是灵活性差,为了支持多种方法要在函数中要写很多分支判断语句。比如,你要计算一个函数值(如sin x,log10 x)的平方,按照传统的方法你可以这样写这个函数:


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


显然,这种方法很费事,造成函数体很长。所以,函数指针的思想很重要。大家可能很熟悉C++中的DDP函数指针类型,那么,在完全面向对象的C#语言中函数指针是什么样子的呢?

在C#中我们使用delegate(委托)关键字来实现函数指针。
在《.NET Framework 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);

以下是完整的程序,在Visual Studio.NET 2003下调试通过:

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:\t{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编程实现函数指针,能够有效的简化代码,提高函数的通用性。 (完)

分享到:
评论

相关推荐

    C# 调用C++DLL(函数参数包含指针)

    本篇文章将深入探讨如何在C#中调用一个C++DLL,特别是当DLL函数参数中包含指针时的处理方法。 首先,理解C#与C++之间的互操作性是关键。.NET框架提供了一个名为P/Invoke(Platform Invoke)的机制,允许C#代码调用...

    调用示例.rar_C#调用c++ dll_C#调用函数指针_C#调用结构体_结构体_调用C dll

    C#调用C++ dll, 包括结构体, 数组, 函数指针, 字符串等等

    C++ 与C#之间的指针参数传递传参参考

    C++ 与C#之间的指针参数传递,实现无限量数据的传递,轻松无压力,方便在C++里面获取或者从C#传递数据到C++的动态库调用内。

    C#结构体指针的定义及使用详解

    通过上述讲解,我们可以了解到在C#中如何定义和使用结构体指针。这对于需要与非托管代码交互或直接操作内存的场景非常有用。不过需要注意的是,使用指针时一定要小心,避免出现未定义行为或安全问题。在实际开发中,...

    C#调用CDLL带指针参数的函数

    本篇将详细讲解如何在C#中调用CDLL,并处理带指针参数的函数。 首先,了解C#与C/C++的区别。C#是一种托管语言,由.NET Framework管理内存,而C/C++是未托管的,内存管理由程序员负责。因此,C#调用C/C++编写的DLL时...

    C# 调用c++ 库 参数为指针类型导出函数

    c# Csharp调用 c++库 参数为导入和导出指针两种 包含C++ DLL源码 如fun(cont char* A,char*B) A为输入参数,B为输出参数-C# CSharp call C++ DLL lib dll function param use export and import eg: fun(cont char*...

    C# csharp指针 案例

    在C#编程语言中,指针是一个特殊的数据类型,它存储了一个变量在内存中的地址,而不是它的实际值。虽然C#作为一个.NET平台上的面向对象语言,其设计初衷是尽可能安全,但为了兼容C/C++代码或者进行底层优化,C#引入...

    C#中的委托类似C++中的函数的指针,功能强大,灵活

    在C#编程语言中,委托(Delegate)是一个强大的特性,它类似于C++中的函数指针,但更加安全和易于使用。委托允许我们将方法作为参数传递给其他方法,或者存储在变量中,以便稍后调用。这使得在C#中实现回调函数和...

    C#中的指针和内存管理以及垃圾回收PPT

    ### C#中的指针、内存管理及垃圾回收详解 #### 指针(Pointer) 在C#编程语言中,虽然直接操作指针的情况较为少见,但确实存在某些应用场景下需要使用到指针。C#设计初衷是为了提供一种更加安全且易于管理内存的方法...

    C++结构体/函数定义转换C#函数定义/结构体

    - C++的函数指针在C#中可以使用委托(Delegate)来表示。 - C++的虚函数在C#中对应为接口(Interface)或抽象类(Abstract Class)。 - C++的模板函数无法直接转换,可能需要创建多个C#方法来模拟。 4. **DLL互...

    C# 实现回调函数

    1. **委托(Delegate)**:C#中的委托是类型安全的函数指针,可以存储一个或多个方法的引用。创建一个委托类型,然后实例化委托对象并将其指向一个或多个方法,这样就可以在适当的时候调用这些方法。例如: ```...

    C#中使用指针源程序,我想许多C程序员不愿意学习Java的原因之一就是Java不支持指针

    C#中使用指针源程序,我想许多C程序员不愿意学习Java的原因就是Java不支持指针,但是现在类似于Java的C#却已经支持了指针,你可以使用unsafe关键字来告诉编译器下面的函数或者代码是不安全的。一旦你使用了unsafe,...

    C#基本函数代码C#基本函数代码C#基本函数代码

    - 委托是类型安全的函数指针,可以用来封装方法。 - 事件是基于委托的通信机制,允许对象之间订阅和触发事件。 8. **异步编程**: - 使用`async`和`await`关键字可以编写非阻塞的异步代码,提高程序性能。 - `...

    C#回调函数示例

    委托是类型安全的函数指针,可以引用一个或多个具有相同签名的方法。这样,我们就可以将一个方法的引用作为参数传递给另一个方法,待合适时机执行。 1. **创建委托** 在C#中,使用`delegate`关键字定义一个新的...

    LabVIEW to C#/C++ 指针读写

    接下来,我们需要在C#或C++中编写函数,接收LabVIEW传递过来的内存指针,然后通过指针读取或写入数据。这通常涉及到unsafe代码块,因为在安全的.NET环境中,直接操作内存是不被允许的。在C++中,我们可以直接操作...

    C#中使用不安全代码(使用指针的代码)

    在C#编程语言中,通常情况下我们不需要使用指针,因为C#提供了丰富的类型系统和安全的内存管理机制。然而,对于某些特定场景,如处理底层数据、优化性能或者与包含指针的库进行交互时,使用不安全代码(即包含指针的...

    成员函数指针与高性能的C++委托

    在C++中,成员函数指针是一种特殊的指针类型,它可以指向类的成员函数。这些成员函数可以是数据成员、成员函数或构造函数。成员函数指针提供了一种方法,使得可以在运行时动态地调用类的成员函数,这对于实现诸如...

    C#在C++中注册回调函数

    `Bridge`类中的`SetManagedCallback`方法接收C++传递过来的函数指针,并将其转换为C#的委托类型,然后调用C#的`SetCallback`方法。 4. **在C++中注册回调函数**: 在C++代码中,我们需要创建一个函数,该函数的...

    C#钩子函数详解\捕捉键盘消息.

    设置钩子的关键函数是`SetWindowsHookEx()`,它接受四个参数:钩子类型(如`WH_KEYBOARD`用于键盘事件)、钩子函数指针、模块句柄(用于DLL)和线程ID。当键盘事件发生时,Windows会调用预先定义的钩子函数。为了...

    1C#中调用API函数方法.pdf

    C#中调用API函数方法 ...本文主要介绍了C#中调用API函数方法的相关知识点,包括调用格式、参数说明、数值类型、字符串类型、指针和结构体等。通过学习这些知识点,读者可以更好地掌握C#中调用API函数的方法。

Global site tag (gtag.js) - Google Analytics