(一)委托
官方对于委托的概述
委托具有以下属性:
- 委托类似于 C++ 函数指针,但委托完全面向对象,不像 C++ 指针会记住函数,委托会同时封装对象实例和方法。
- 委托允许将方法作为参数进行传递。
- 委托可用于定义回调方法。
- 委托可以链接在一起;例如,可以对一个事件调用多个方法。
- 方法不必与委托类型完全匹配。
- 使用 Lambda 表达式可以更简练地编写内联代码块。 Lambda 表达式(在某些上下文中)可编译为委托类型。
委托用于将方法作为参数传递给其他方法。 事件处理程序就是通过委托调用的方法。 您可以创建一个自定义方法,当发生特定事件时某个类(例如 Windows 控件)就可以调用您的方法。
Action委托
可以使用此委托将方法作为参数传递,而无需显式声明自定义委托。 封装的方法必须与此委托定义的方法签名相对应。 这意味着封装的方法必须没有参数,也没有返回值。我们这里定义了一个没有传参也没有返回值的方法,方法为打印一段文字。
class Calator
{
public void ActionCa()
{
Console.WriteLine("你好");
}
}
现在我们将该方法创建出来,并且再创建出一个Action委托。
static void Main(string[] args)
{
Calator calator = new Calator();
calator.ActionCa();
Action action = new Action(calator.ActionCa);
action.Invoke();
}
我们执行代码就会得到如下效果。
Func委托
可以使用此委托来表示可以作为参数传递的方法,而无需显式声明自定义委托。 封装的方法必须与此委托定义的方法签名相对应。 这意味着封装的方法必须有返回值。我们这里定义了一个返回值为int类型并且传入两个int参数的方法,返回一个两数相乘的数。
class Calator
{
public int Add(int a, int b)
{
return a * b;
}
}
现在我们将该方法创建出来,并且再创建出一个Func委托,并且传入10与20,我们这里定义一个int a来接收Add方法的返回值。
static void Main(string[] args)
{
Calator calator = new Calator();
Func<int, int, int> func = new Func<int, int, int>(calator.Add);
int a = func.Invoke(10, 20);
Console.WriteLine(a);
}
我们执行代码会得到如下效果。
自定义委托
自定义委托关键字delegate,我们现在定义一个返回参数为double类型,并且接收两个double类型的自定义委托,这里命名为Calc,现在我们对该委托进行创建,并且向其传入两个值2.0与4.5,方法中我们定义的是两个值的相加的返回值,我们用一个double类型b来接收。
public delegate double Calc(double x, double y);
internal class Program
{
static void Main(string[] args)
{
Calator calator = new Calator();
Calc calc = new Calc(calator.Sdd);
double b = calc.Invoke(2.0, 4.5);
Console.WriteLine(b);
}
}
class Calator
{
public double Sdd(double a, double b)
{
return a + b;
}
}
我们执行代码,会得到如图效果。
委托慎用 !可能会导致代码变的难以维护,可读性下降,导致内存泄漏或者程序性能下降!
(二)值类型引用参数
引用参数是用ref关键字修饰符声明的形参,变量在可以作为引用形参传递之前,必须先明确赋值,我们创建一个带有引用参数传参的方法。
static void RefPost(ref int x)
{
x = x + 1;
}
现在我们对这个方法进行引用,并且定义一个int类型的值y=100,并且传入到RefPost方法中,我们在传参的时候也是需要带ref关键字的。
static void Main(string[] args)
{
int y = 100;
RefPost(ref y);
}
现在我们往RefPost方法中传递了一个引用参数,如果我们现在在传递完参数之后,并且在Main方法中对int类型的y打印出来,我们会得到什么呢?
我们看到打印出来的值是101,为什么是101呢?不应该只是RefPost方法中的x值为101吗?为什么Main方法中的y也改变为了101?
这是因为我们RefPost方法中的传参参数x指向的地址是Main方法中我们所定义的y的地址,也就是说,我们在使用ref关键字修饰的引用传参时,无论是RefPost方法中的x改变还是Main方法中的y改变,他们的关系是x=y(y=x)。