C#委托的20种表达方式,每一种优缺点和应用场景

C#委托有多种表达方式,每一种都有各自的优缺点和适用场景。以下为常见的20种表达方式:

1. 声明委托类型,并使用委托关键字进行定义:
```c#
delegate void MyDelegate(int value);
```
优点:简单明了,易于理解和使用。
缺点:需要额外的代码定义委托。

2. 使用匿名方法:
```c#
MyDelegate myDelegate = delegate(int value) { Console.WriteLine(value); };
```
优点:简洁,无需显式定义委托。
缺点:不能重用匿名方法。

3. 使用Lambda表达式:
```c#
MyDelegate myDelegate = (value) => { Console.WriteLine(value); };
```
优点:简洁,可用于替代匿名方法。
缺点:不能重用Lambda表达式。

4. 使用命名方法:
```c#
void MyMethod(int value)
{
Console.WriteLine(value);
}

MyDelegate myDelegate = MyMethod;
```
优点:便于重用和维护,可在不同的地方使用同一个方法。
缺点:需要通过方法名来引用委托。

5. 使用实例方法:
```c#
class MyClass
{
public void MyMethod(int value)
{
Console.WriteLine(value);
}
}

MyClass myObject = new MyClass();
MyDelegate myDelegate = myObject.MyMethod;
```
优点:可以将对象的实例方法作为委托进行调用。
缺点:需要先创建对象实例。

6. 使用静态方法:
```c#
class MyClass
{
public static void MyMethod(int value)
{
Console.WriteLine(value);
}
}

MyDelegate myDelegate = MyClass.MyMethod;
```
优点:可以将类的静态方法作为委托进行调用。
缺点:无法访问非静态类成员。

7. 使用多播委托:
```c#
MyDelegate myDelegate1 = (value) => { Console.WriteLine(value); };
MyDelegate myDelegate2 = (value) => { Console.WriteLine(value * 2); };
MyDelegate myDelegate = myDelegate1 + myDelegate2;
```
优点:可以将多个委托合并为一个委托进行调用。
缺点:可能会导致难以预测的行为和性能问题。

8. 使用null委托:
```c#
MyDelegate myDelegate = null;
```
优点:可用于初始化委托变量。
缺点:无法调用空委托。

9. 使用泛型委托:
```c#
delegate void MyDelegate<T>(T value);
MyDelegate<int> myDelegate = (value) => { Console.WriteLine(value); };
```
优点:可以定义适用于不同类型的委托。
缺点:需要声明和使用泛型类型。

10. 使用Func<>委托:
```c#
Func<int, int, int> myDelegate = (x, y) => { return x + y; };
```
优点:可以定义具有多个参数和返回值的委托。
缺点:仅适用于特定的函数签名。

11. 使用Action<>委托:
```c#
Action<int> myDelegate = (value) => { Console.WriteLine(value); };
 //传递两个参数            

 Action<string, int> action = new Action<string, int>(ShowAction);            

 Show("张三",29,action);            

 //传递一个参数            

 Show("张三",() =>Console.WriteLine(o));             

//不传递参数调用             

Show(()=>Console.WriteLine("张三"));
优点:用于不返回任何值的方法。
缺点:仅适用于特定的函数签名。

12. 使用Predicate<>委托:
```c#
Predicate<int> myDelegate = (value) => { return value > 0; };
```
优点:用于返回布尔值的方法。
缺点:仅适用于特定的函数签名。

13. 使用委托的BeginInvoke和EndInvoke方法:
```c#
MyDelegate myDelegate = (value) => { Console.WriteLine(value); };
myDelegate.BeginInvoke(10, null, null);
```
优点:可以异步调用委托方法。
缺点:需要额外处理异步操作。

14. 使用事件和事件处理程序:
```c#
class MyEventClass
{
public event MyDelegate MyEvent;

public void InvokeEvent(int value)
{
MyEvent?.Invoke(value);
}
}

MyEventClass myEventObject = new MyEventClass();
myEventObject.MyEvent += (value) => { Console.WriteLine(value); };
```
优点:用于建立发布者和订阅者之间的通信。
缺点:需要显式定义事件和事件处理程序。

15. 使用委托的异步回调:
```c#
MyDelegate myDelegate = (value) => { Console.WriteLine(value); };
IAsyncResult result = myDelegate.BeginInvoke(10, (asyncResult) => { myDelegate.EndInvoke(asyncResult); }, null);
```
优点:可以在异步操作完成后进行回调处理。
缺点:复杂,需要处理回调方法和参数。

16. 使用委托的过滤和排序算法:
```c#
List<int> numbers = new List<int> { 3, 1, 2, 4 };
List<int> filteredNumbers = numbers.FindAll((value) => { return value > 2; });
filteredNumbers.Sort();
```
优点:可用于筛选和排序集合中的元素。
缺点:需要传递筛选和排序的条件。

17. 使用委托进行事件触发:
```c#
class MyEventClass
{
public event MyDelegate MyEvent;

public void InvokeEvent(int value)
{
MyEvent?.Invoke(value);
}
}

MyEventClass myEventObject = new MyEventClass();
myEventObject.MyEvent += (value) => { Console.WriteLine(value); };
myEventObject.InvokeEvent(10);
```
优点:可以通过事件触发委托的调用。
缺点:需要显式定义事件和事件处理程序。

18. 
Action myAction = new Action(() =>
{
m_CtrlHStatusLabelCtrl.Visible = false;
barVisible_strip.Enabled = false;
viewWindow.ClearWindow();
});
myAction();

应用场景:

  1. 当需要在某个特定的时间点执行一系列操作,而这些操作不需要传递任何参数和返回任何值时,可以使用Action委托来表示这个方法。
  2. 当需要传递一个方法作为参数给其他方法时,而这个方法不需要返回任何值时,可以使用Action委托来传递。

优点:

  1. 简化代码实现:使用Action委托可以将一系列操作封装在一个委托中,从而减少冗余的代码。
  2. 提高代码可读性:使用Action委托可以使代码更加清晰,易于理解,从而提高代码的可读性。

缺点:

  1. 由于Action委托表示的方法没有返回值,所以在某些情况下可能需要额外的处理来获取到方法执行的结果。
  2. 由于Action委托表示的方法没有参数,所以在某些情况下可能需要额外的处理来传递方法所需的参数。

19. 多线程环境下,通过主线程来执行某些操作或更新UI元素。

this.Invoke(new Action(() =>
{
GrayInformation_LB.Visible = true;
HWinControl.HalconWindow.ClearWindow();
tool.ClearWindow();
}));

优点:

  1. 确保在UI线程上执行:在多线程应用程序中,如果在非UI线程上更新UI元素,将导致无法访问并修改UI元素,从而引发异常。通过使用Invoke方法,可以确保在UI线程上执行指定的代码,避免了跨线程访问UI元素。

  2. 线程同步:在多线程环境下,如果多个线程同时修改同一个UI元素,可能会引发竞态条件(race condition)和其他线程同步问题。通过使用Invoke方法,可以将多个线程的操作序列化,确保一次只有一个线程修改UI元素,从而避免了线程同步问题。

缺点:

  1. 性能开销:由于使用了Invoke方法,再加上线程切换的开销,可能会导致一定的性能损失。在UI更新频繁的场景下,如果过多地使用Invoke方法,可能会影响程序的响应性能。

  2. 可能引发死锁:如果在UI线程中调用了正在等待UI线程响应的其他线程,可能会导致死锁问题。因此,在使用Invoke方法时,需要注意避免在UI线程中等待其他线程的响应。

总结:这种委托调用主要是为了确保在UI线程上执行操作和修改UI元素,并避免多线程同步问题。但需要注意,合理使用委托调用,避免性能问题和死锁问题的发生

20. 使用委托进行并行操作:
```c#
List<int> numbers = new List<int> { 1, 2, 3, 4 };
Parallel.ForEach(numbers, (value) => { Console.WriteLine(value); });

this.Invoke(new Action(() =>
{
timer = new System.Timers.Timer(1000); // 1000 毫秒 = 1 秒

// 当倒计时结束时,触发事件
timer.Elapsed += (sender, e) =>
{

};
timer.Stop(); // 停止计时器,避免重复触发事件
timer.AutoReset = true;
timer.Enabled = true;
//HOperatorSet.cleanClearWindow(hv_window);
}
));


优点:可以并行处理集合中的元素。
缺点:需要使用并行操作的方式(例如Parallel类)。


posted @ 2023-07-25 22:01  专注视觉  阅读(666)  评论(0编辑  收藏  举报