C# 备忘清单 & cs cheatsheet & 速查表

介绍

在 .NET 中,委托支持后期绑定,允许调用方在运行时提供方法的一部分,而不是在创建委托时定义完整算法,从而增强了灵活性和扩展性。

多播委托

我们预先提供这些可用的方法

public void Sub(int x, int y)
{
    Console.WriteLine("x-y=" + (x - y));
}

public void Mul(int x, int y)
{
    Console.WriteLine("x*y=" + (x * y));
}

定义一个委托类型

public delegate void MyDelegate3(int x, int y);

定义一个方法,接收委托作为参数

public void MyMethod3(int x, int y, MyDelegate3 myDelegate)
{
    myDelegate(x, y);
}

定义另一个委托类型

public delegate void MyDelegate4(int x, int y);

定义一个方法,接收委托作为参数

public void MyMethod4(int x, int y, MyDelegate4 myDelegate)
{
    myDelegate(x, y);
}

定义一个方法,接收委托作为参数

public void MyMethod5(int x, int y, MyDelegate3 myDelegate, MyDelegate4 myDelegate2)
{
    myDelegate(x, y);
    myDelegate2(x, y);
}

多播委托

MyDelegate3 myDelegate31 = new MyDelegate3(Sub);
MyDelegate4 myDelegate41 = new MyDelegate4(Mul);

调用 MyMethod3 方法,并传入委托作为参数

MyMethod3(10, 5, myDelegate31);
// output:
// x-y=5

调用 MyMethod4 方法,并传入委托作为参数

MyMethod4(10, 5, myDelegate41);
// output:
// x*y=50

调用 MyMethod5 方法,并传入委托作为参数

MyMethod5(10, 5, myDelegate31, myDelegate41);
// output:
// x-y=5
// x*y=50

定义委托类型

使用 delegate 关键字定义委托

public delegate void MyDelegate(
    int x, string y
);

上述委托对应的函数实现应该类似:

public void MyMethod(int x, string y);

创建委托实例

// 创建委托实例
MyDelegate myDelegate = new MyDelegate(
    MyMethod
);

调用委托

// 调用委托,传入对应类型的参数
myDelegate(10, "Hello");

委托作为参数

// 定义另一个委托类型
public delegate int MyDelegate2(
    int x, int y
);

// 定义一个方法,接收委托作为参数
public int MyMethod2(
   int x, int y, MyDelegate2 myDelegate
)
{
    return myDelegate(x, y);
}

// 创建委托实例
MyDelegate2 myDelegate2 = new MyDelegate2(
    Add
);

// 调用 MyMethod2 方法,并传入委托作为参数
int result = MyMethod2(
    10, 20, myDelegate2
);

Action 委托

Action 委托的变体最多可包含 16 个参数,且返回类型为 void

// 创建一个Action
public Action<int, string> myAction;

// 给Action赋值
myAction = (x, y) => Console.WriteLine(
    "x+y=" + (x + y)
);

// 直接调用Action
myAction(10, "Hello");

// 使用 null 合并运算符调用Action
myAction?.Invoke(10, "Hello");

Func 委托

Func 委托的变体可包含最多16个参数,返回类型可以是任意类型 T

// 创建一个Func,最后一个参数是返回类型
public Func<int, int, string> myFunc;

// 给Func赋值
myFunc = (x, y) => "x+y=" + (x + y);

// 调用Func
string result = myFunc(10, 20);

// 使用 null 合并运算符调用Func
string result2 = myFunc?.Invoke(10, 20);

事件与委托类似,都是后期绑定机制。实际上,事件是建立在委托基础上的一种语言支持,它是 C# 对委托的封装,提供了更面向对象的编程模型,并实现了观察者模式。

事件定义

// 使用 event 关键字定义事件
public event EventHandler<EventArgs> MyEvent;

事件订阅

我们实现定义一个方法作为事件处理器,并订阅事件

public void MyEventHandler(object sender, EventArgs e)
{
    // 事件处理逻辑
    // ...
}
// 订阅事件
MyEvent += MyEventHandler;

// 取消订阅事件
MyEvent -= MyEventHandler;

事件触发

// 触发事件
MyEvent?.Invoke(this, new EventArgs());

事件参数

// 定义事件参数
public class MyEventArgs : EventArgs
{
    public int Value { get; set; }
}

// 新的Handler
public void MyEventHandler2(object sender, MyEventArgs e)
{
    // 事件处理逻辑,这里可以获取到事件参数
    Console.WriteLine("事件参数的值:" + e.Value);
}

// 触发事件
// output:
// 事件参数的值:10
MyEvent?.Invoke(this, new MyEventArgs { Value = 10 });