我读了很多关于代表的文章,是的,起初语法很混乱。我发现 this article the most useful. 示例2 使得如何使用委托变得非常容易理解。但我已经将这些代码提供给我并使用它:
public delegate bool IntPredicate(int x);
public delegate void IntAction(int x);
class IntList : List<int>
{
public IntList(params int[] elements) : base(elements)
{
}
public void Act(IntAction f)
{
foreach (int i in this)
{
f(i);
}
}
public IntList Filter(IntPredicate p)
{
IntList res = new IntList();
foreach (int i in this)
if (p(i))
res.Add(i);
return res;
}
}
现在,让我感到困惑的是f
和p
函数中的Act
和Filter
变量。在教程中,这些函数似乎是正常的,具有正常类型的属性,但这里的属性属于委托函数类型,我会受到混淆。
请你就此事劝我一下吗?
答案 0 :(得分:3)
委托只是一种类型。使用您习惯的类型(例如int
,string
等),当您想要使用它们时,您可以使用框架中的一个或者声明自己的类型。您可以对代理执行完全相同的操作 - 使用预先构建的代理(如System.Action
)或声明您自己的代码,这是在此处完成的。
因此,在您的代码段中,声明了3种类型:
public delegate bool IntPredicate(int x);
public delegate void IntAction(int x);
class IntList : List<int> { ... }
您会注意到委托声明与类声明处于同一级别。
如果您有类型(如此处的IntPredicate
),则可以将其用于变量或函数参数。现在的问题是:你如何设置变量的值,然后用它做什么?
使用普通变量,您只需传入值。像这样:
string text = "Hello world";
原则与代理相同,但是,当然,你必须传递一些委托类型或可以转换为它的东西。您有几种选择:
现有方法
如果方法的签名(即返回值和参数)与委托的签名匹配,则可以传入方法。所以,你可以这样做:
void WriteIntAction(int value)
{
Console.WriteLine(value);
}
/* then, in some other method */
IntList intList = new IntList(1,2,3);
intList.Act(WriteIntAction);
匿名方法
有几种方法可以创建匿名方法。我将使用lambda表达式,因为这是最简单的。如果你曾经使用过任何函数式语言,那就应该很熟悉了。
IntList intList = new IntList(1,2,3);
intList.Act(x => Console.WriteLine(x));
因此,在使用您需要的方法(无论是现有方法还是匿名方法)设置变量后,您可以像使用任何方法一样使用委托变量。这就是这一行:
f(i);
请注意,委托是一种引用类型,因此f
的值可以是null
,当您尝试调用委托时,它会抛出异常。
<强> TL; DR 强>
委托是一种类型。您可以在变量或方法参数中使用它。您可以仅使用其名称传递方法,也可以创建匿名方法。然后,您可以像使用方法一样使用变量来调用传递给它的方法。
您可以在线阅读更多内容,例如:http://msdn.microsoft.com/en-us/library/ms173171.aspx
答案 1 :(得分:1)
对于所有意图和目的,委托类型只是一个函数(或者如果您是C ++用户,则类似于函数指针)。换句话说,你将它们称为函数,就像示例代码所做的那样。
f(i)
调用传递的函数,并将i
变量作为其唯一参数,就像它看起来一样。