首页 > 解决方案 > 我可以在 C# 中的一行中定义委托、实例和代码吗?

问题描述

目前,要定义一个事件挂钩,我正在写:

delegate void WinEventHookDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

...

private WinEventHookDelegate WindowEventHookInstance;

...

private void WindowEventHook(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)

...

WindowEventHookInstance = new WinEventHookDelegate(WindowEventHook);
        Install();

...

SetWinEventHook(...
                WindowEventHookInstance,     // lpfnWinEventProc
                ...);

...

即,我正在创建 3 个名称(WinEventHookDelegate, WindowEventHookInstance, WindowEventHook)、2 个重复的原型声明和 1 个分配以仅获取指向函数的指针。

我可以把它写得更少冗余和更短,也许在一行?

标签: c#delegates

解决方案


您可以使用 C# 的委托而不是定义自己的委托。

对于在您的情况下指向 void 函数的委托,您可以使用 Action。

您可以像这样直接将其粘贴在您的 SetWinEventHook 方法中,而不是声明和实例化委托(或在本例中为操作委托)。编译器将负责实例化。

public void SetWinEventHook(Action<IntPtr, uint, IntPtr, int, int, uint, uint> myDelegate)
{

}

现在为了启动您的代表指向您的功能,请执行此操作

myDelegate() 

然而,问题是这个委托需要你声明它需要的 7 个参数。

为了提供您可以像这样在 SetWinEventHook 方法中将它们作为第二个参数传递

 public void SetWinEventHook(Action<IntPtr, uint, IntPtr, int, int, uint, uint> myDelegate, IntPtr a, uint b, IntPtr c, int d, int e, uint f, uint g)
 {
     myDelegate(a,b,c,d,e,f,g);
 }

所以在这一点上,你基本上

1) 声明一个代表

2) 实例化一个委托

3) 创建了一个钩子方法来启动委托/函数

现在您需要做的就是调用您的 SetWinEventHook 并传入一个 lambda 或在其他地方编写的函数,以便您的委托将指向它。

     SetWinEventHook((a, b, c, d, r, f, g) => // using lambda here
     {

     },
      new IntPtr(), 1, new IntPtr(), 2,3,4,5
     );

推荐阅读