Могу ли я определить делегат, его экземпляр и его код в одной строке в C #?

#c# #delegates

#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 присваивание, чтобы получить только указатель на функцию.

Могу ли я написать его менее избыточным и короче, может быть, в одной строке?

Комментарии:

1. Слишком много ... и слишком мало { } . Важная часть, SetWinEventHook, также не определена.

2. @HenkHolterman это из WinApi:learn.microsoft.com/en-us/windows/desktop/api/winuser /…

Ответ №1:

Вы можете использовать делегаты 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) Создал метод hook для запуска делегата / функции

Теперь все, что вам нужно сделать, это вызвать SetWinEventHook и передать либо лямбда-выражение, либо функцию, написанную в другом месте, чтобы ваш делегат указывал на нее.

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

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