什么是C# 委托?这篇文章让你困惑全摆脱


什么是C# 委托?这篇文章让你困惑全摆脱

文章插图
作者 | 羽生结弦
责编 | 胡雪蕊
出品 | CSDN(CSDNnews)
在C#中的委托关键字是 Delegate,委托类似于C/C++中函数的指针 。是存有对某个方法引用的引用类型变量,可在运行时被改变 。一般用于实现事件和回调方法 。
注意:所有的委托都派生自 System.Delegate 类委托分为 委托类型和委托实例,下面分别进行讲解 。
 1.零、委托类型和委托实例 
1. 委托类型
委托类型定义了委托实例可以调用的方法、方法的返回类型和参数 。我们可以通过委托类型的返回类型和参数来得知具体可以调用哪种方法 。下面我们通过一个例子来看一下:
(1)首先我们定义一个委托类型:
 csharp
delegate string DemoDelegate(int num);
(2)其次我们定义两个方法:
 csharp
string IntToString(int num)
{
return num.ToString;
}
int StringToInt(string num)
{
return int.Parse(num);
}
我们来分析一下这两个代码段 。首先我们定义了一个委托 DemoDelegate,委托所定义的返回值类型是 string 类型,参数只包含一个,参数类型是 int 。因此根据委托定义得知只有方法的返回值类型是 string 且参数只有一个,并且 参数类型是 int 时,委托才能调用 。所以符合条件的方法就只有IntToString 。
2. 委托实例
当把方法赋值给委托变量的时候就创建了委托实例 。同样我们用一个例子来看一下:
 csharp
static void Main(string[] args)
{
DemoDelegate dd = IntToString;
string num = dd(123);
// 将输出 string 类型 "123"
Console.WriteLine(num);
}
委托实例本质上就是调用者委托委托方法调用被调用者,在这里就是 Main 方法委托DemoDelegate 去调用 IntToString 方法 。这样做的好处是调用者和被调用者的耦合度降低了 。
小知识:上面的代码我们还可以这样写,这两种写法是等价的:
 csharp
static void Main(string[] args)
{
DemoDelegate dd = new DemoDelegate(IntToString);
string num = dd.Invoke(123);
// 将输出 string 类型 "123"
Console.WriteLine(num);
}
委托的用途很多,我们这里来看一个例子,这个例子展示了委托其中一种的用途
 csharp
public delegate int DemoDelegate(int num);
class Tool
{
public static void IntSquare(int[] intArray, DemoDelegate dd)
{
for (int i = 0; i < intArray.Length; i++)
{
intArray[i] = dd(intArray[i]);
}
}
}
class Program
{
static void Main(string[] args)
{
DemoDelegate dd = Square;
int intArray = {2,4,6 };
Tool.IntSquare(intArray, dd);
for (int i = 0; i < intArray.Length; i++)
{
Console.WriteLine(intArray[i]);
}
Console.Read;
}
static int Square(int num)
{
return num * num;
}
}
我们将委托提取出来,作为一个公共的,然后定义一个 Tool 类,其中定义了一个计算数组中每个值的方法,这个方法接受两个参数,一个是int类型的数组,另一个是 DemoDelegate 委托类型的参数 。通过委托调用 Program 类中的 Square 方法来计算数组中每个数字的平方值 。我们在 Main方法中将 Square 方法赋值给委托变量,然后见数组和委托变量一同传入刚才我们定义的 Tool 类中的 IntSquare 方法,最后输出值为:4、16、36 。这种用途叫做编写插件式方法,插件式方法就是只有在运行时才将方法赋值给委托 。
 2.多播委托 
前面的例子我们都是讲一个方法赋值给委托变量,这种叫单播委托 。但是在大部分情况下我们需要将多个方法赋值给委托,这是我们就用到了多播委托 。要把多个方法赋值给委托变量,我们需要用到 +和 +=,方法如下:
 csharp
Delegate d = method1;
d += method2;
当我们调用委托 d 的时候,就会按照赋值顺序来调用方法,即先调用 method1 再调用 method2。我们有时候也需要移除委托中的某个方法,这时我们可以用 - 和 -= 进行操作,比如我们移除前面例子中的 method1 方法:
 csharp
d -= method1;
当我们进行 + 或者 += 操作时,操作数可以是,相当于把一个新值赋值给了委托变量,也就是说如下两种方法是等价的:
方法一:
 csharp
Delegate d = ;
d += method1;
方法二:


推荐阅读