C#中委托的用法及进阶
2025-04-19 13:44:24 # 奇奇怪怪的知识

在 C# 中,委托(delegate)是一种引用类型,用于封装一个或多个方法。它类似于函数指针,但更安全且更灵活。委托在事件处理和回调函数中广泛使用。以下是一些关于委托的详细用法和示例:

1. 委托的定义和实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 定义一个委托
public delegate void MyDelegate(string message);

public class Program
{
// 定义一个与委托匹配的方法
public static void ShowMessage(string message)
{
Console.WriteLine(message);
}

public static void Main()
{
// 实例化委托
MyDelegate del = new MyDelegate(ShowMessage);
// 使用委托调用方法
del("Hello, Delegates!");
}
}

2. 多播委托

一个委托实例可以引用多个方法,形成一个调用列表。当调用委托时,会依次调用列表中的所有方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public delegate void MyDelegate(string message);

public class Program
{
public static void ShowMessage(string message)
{
Console.WriteLine("ShowMessage: " + message);
}

public static void ShowAnotherMessage(string message)
{
Console.WriteLine("ShowAnotherMessage: " + message);
}

public static void Main()
{
MyDelegate del = ShowMessage;
del += ShowAnotherMessage;

del("Hello, Multicast Delegates!");

// 移除一个方法
del -= ShowMessage;
del("Hello, after removing one method!");
}
}

3. 委托作为参数

委托可以作为方法的参数,用于实现回调机制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public delegate void ProcessHandler(string message);

public class Processor
{
public void Process(ProcessHandler handler, string message)
{
handler(message);
}
}

public class Program
{
public static void ShowMessage(string message)
{
Console.WriteLine("Processing: " + message);
}

public static void Main()
{
Processor processor = new Processor();
processor.Process(ShowMessage, "Hello, Delegate as Parameter!");
}
}

4. 内置委托类型(Func, Action, Predicate)

C# 提供了一些内置的委托类型,如 Func、Action 和 Predicate,简化了委托的使用。

  • Action:用于没有返回值的方法。
  • Func:用于有返回值的方法。
  • Predicate:用于返回 bool 类型的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Program
{
public static void ShowMessage(string message)
{
Console.WriteLine("Action: " + message);
}

public static int Add(int x, int y)
{
return x + y;
}

public static bool IsPositive(int number)
{
return number > 0;
}

public static void Main()
{
Action<string> action = ShowMessage;
action("Hello, Action!");

Func<int, int, int> func = Add;
int result = func(3, 4);
Console.WriteLine("Func result: " + result);

Predicate<int> predicate = IsPositive;
bool isPositive = predicate(5);
Console.WriteLine("Predicate result: " + isPositive);
}
}

5. 匿名方法和 Lambda 表达式

委托可以使用匿名方法和 lambda 表达式来简化代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public delegate void MyDelegate(string message);

public class Program
{
public static void Main()
{
// 匿名方法
MyDelegate del = delegate (string msg)
{
Console.WriteLine("Anonymous method: " + msg);
};
del("Hello, Anonymous!");

// Lambda 表达式
MyDelegate del2 = (msg) => Console.WriteLine("Lambda: " + msg);
del2("Hello, Lambda!");
}
}

6. 委托和事件

委托是事件的基础,用于定义事件处理程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Publisher
{
public delegate void MyEventHandler(string message);
public event MyEventHandler RaiseCustomEvent;

public void DoSomething()
{
OnRaiseCustomEvent("Event triggered!");
}

protected virtual void OnRaiseCustomEvent(string message)
{
RaiseCustomEvent?.Invoke(message);
}
}

public class Subscriber
{
public void HandleCustomEvent(string message)
{
Console.WriteLine("Event received: " + message);
}
}

public class Program
{
public static void Main()
{
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();

publisher.RaiseCustomEvent += subscriber.HandleCustomEvent;
publisher.DoSomething();
}
}