C# 代表的作用是什么?
可能重复:C# 代表的作用是什么?,c#,.net,C#,.net,可能重复: 我创建了一个示例应用程序。我真的很难理解为什么要使用代表,因为没有代表,我们可以实现一切 class Program { public delegate double Integrand(double x); static double MyFunc1(double x) { return x + 10; } static double MyFunc2(double x) { return x + 20; } public static doubl
我创建了一个示例应用程序。我真的很难理解为什么要使用代表,因为没有代表,我们可以实现一切
class Program
{
public delegate double Integrand(double x);
static double MyFunc1(double x) { return x + 10; }
static double MyFunc2(double x) { return x + 20; }
public static double Gauss3DelMethod(Integrand f)
{
double a = f(1);
return a;
}
public static double Gauss3SimpleMethod(double x)
{
double a = x;
return a;
}
static void Main(string[] args)
{
//with delegates
double res = Gauss3DelMethod(MyFunc1);
double res1 = Gauss3DelMethod(MyFunc2);
//without delegates
double res2 = Gauss3SimpleMethod(MyFunc1(1));
double res3 = Gauss3SimpleMethod(MyFunc2(1));
int i = 0;
}
}
那么,我为什么要使用委托呢?在您的特定示例中,这可能并不重要。(目前尚不清楚它试图实现什么目标。) 但是,假设您想让该方法对几个不同的输入执行相同的
MyFunc1
或MyFunc2
。例如,假设您正在实现,以对常规函数进行操作。在这种情况下,您不能一次调用函数并将其传递到方法中-您希望将实际函数传递到方法中,以便方法可以使用它需要的任何输入调用它
类似的例子是排序。例如,使用LINQ可以编写如下内容:
var sorted = people.OrderBy(x => x.Age).ToList();
在这里,我们传递一个函数,将每个源元素投影到排序键。我们不必自己执行该函数-OrderBy
将为我们(懒洋洋地)执行该函数
当然,所有这些都可以通过单方法接口来完成——委托和单方法接口有很多共同点。但是,与单一方法接口相比,代理具有以下优点:
- 代理是多播的-它们可以合并/删除,通常是为了事件
- 您可以使用BeginInvoke/EndInvoke异步执行它们
- 您可以使用匿名方法和lambda表达式构建它们
- 您可以通过使用lambda表达式的表达式树将逻辑表示为数据;然后可以将它们编译为委托
- 您可以从具有适当签名的任何方法构建委托-例如,单个类可以有多个方法“实现”同一委托类型,而您不能在一个类中多次实现接口
- 同样地,委托实现方法可以是私有的,而接口方法必须是公共的(或者通过显式接口实现某种程度上是公共的)
总之:学员非常有用。仅仅因为您编写了一些并不特别需要它们的琐碎代码,并不意味着它们没有用处。我强烈建议您研究LINQ、事件处理程序和TPL,它们都大量使用委托。在您的特定示例中,这可能并不重要。(目前尚不清楚它试图实现什么目标。) 但是,假设您想让该方法对几个不同的输入执行相同的
MyFunc1
或MyFunc2
。例如,假设您正在实现,以对常规函数进行操作。在这种情况下,您不能一次调用函数并将其传递到方法中-您希望将实际函数传递到方法中,以便方法可以使用它需要的任何输入调用它
类似的例子是排序。例如,使用LINQ可以编写如下内容:
var sorted = people.OrderBy(x => x.Age).ToList();
在这里,我们传递一个函数,将每个源元素投影到排序键。我们不必自己执行该函数-OrderBy
将为我们(懒洋洋地)执行该函数
当然,所有这些都可以通过单方法接口来完成——委托和单方法接口有很多共同点。但是,与单一方法接口相比,代理具有以下优点:
- 代理是多播的-它们可以合并/删除,通常是为了事件
- 您可以使用BeginInvoke/EndInvoke异步执行它们
- 您可以使用匿名方法和lambda表达式构建它们
- 您可以通过使用lambda表达式的表达式树将逻辑表示为数据;然后可以将它们编译为委托
- 您可以从具有适当签名的任何方法构建委托-例如,单个类可以有多个方法“实现”同一委托类型,而您不能在一个类中多次实现接口
- 同样地,委托实现方法可以是私有的,而接口方法必须是公共的(或者通过显式接口实现某种程度上是公共的)
总之:学员非常有用。仅仅因为您编写了一些并不特别需要它们的琐碎代码,并不意味着它们没有用处。我强烈建议您研究LINQ、事件处理程序和TPL,它们都大量使用委托。委托是传递函数的有用方式。
Func
和Action
也是代理。如果没有它们,就无法使用几乎所有的LINQ方法,从C#3.0开始,可以使用Lambda表达式更快地创建它们
例如,假设您有一个可枚举的整数:
var numbers = Enumerable.Range(0, 100);
通过使用委托,您可以创建高阶函数(),该函数可以帮助您以多种方式筛选,例如,上面的数字<代码>其中是一种情况
您可能只需要选择奇数:
var odd = numbers.Where(a => a % 2 == 0);
甚至是:
var even = numbers.Where(a => a % 2 != 0);
如果没有它们,您必须为每个筛选器创建一个方法(例如,
WhereOdd
或WhereEven
)委托是传递函数的有用方式。
Func
和Action
也是代理。如果没有它们,就无法使用几乎所有的LINQ方法,从C#3.0开始,可以使用Lambda表达式更快地创建它们
例如,假设您有一个可枚举的整数:
var numbers = Enumerable.Range(0, 100);
通过使用委托,您可以创建高阶函数(),该函数可以帮助您过滤,例如,numb