C# 与学员一起解释此代码

C# 与学员一起解释此代码,c#,delegates,C#,Delegates,我读了很多关于委托的文章,是的,一开始语法很混乱。我发现示例2使如何使用代理变得非常容易理解。但我有这个代码给我,并与它一起工作: public delegate bool IntPredicate(int x); public delegate void IntAction(int x); class IntList : List<int> { public IntList(params int[] elements) : base(elements) {

我读了很多关于委托的文章,是的,一开始语法很混乱。我发现示例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;
    }
}
公共委托bool IntPredicate(intx);
公共代表无效声明(int x);
类IntList:List
{
公共IntList(参数int[]元素):基本(元素)
{
}
《公共无效法》(第f章)
{
foreach(本文件中的int i)
{
f(i);
}
}
公共IntList筛选器(INTP)
{
IntList res=新的IntList();
foreach(本文件中的int i)
如果(p(i))
第3(i)项决议;
返回res;
}
}
现在,让我困惑的是
Act
Filter
函数中的
f
p
变量。正如在教程中一样,这些函数似乎是正常的,它们的属性是正常类型的,但这里的属性是委托函数类型的,我很困惑


你能给我一点启发吗?

< P>一个委托类型,对于所有意图和目的来说,只是一个函数(或者如果你是C++用户,类似于函数指针)。换句话说,调用它们就像调用函数一样,这正是示例代码所做的


<> >代码> f(i)< />调用调用的函数,以<代码> i <代码>变量作为唯一的参数,正如它所看到的。

委托类型是,出于所有意图和目的,只是一个函数(或者如果您是C++用户,类似于函数指针)。换句话说,调用它们就像调用函数一样,这正是示例代码所做的


f(i)
调用传递的函数,并将
i
变量作为其唯一参数,就像它看起来一样。

委托只是一种类型。对于您习惯的类型(如
int
string
等),当您想要使用它们时,您可以使用框架中的类型,也可以声明自己的类型。您可以对代理执行完全相同的操作-使用预构建的代理(如
System.Action
)或声明您自己的代理,这就是此处所做的

因此,在您的代码片段中,声明了3种类型:

public delegate bool IntPredicate(int x);
public delegate void IntAction(int x);

class IntList : List<int> { ... }
委托的原理是相同的,但是,当然,您必须传入委托类型的内容或可以转换为委托类型的内容。您有几个选择:

现有方法

如果方法的签名(即返回值和参数)与委托的签名匹配,则可以传入方法。所以,你可以这样做:

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

委托是一种类型。您可以在变量或方法参数中使用它。可以仅使用方法的名称传递方法,也可以创建匿名方法。然后,可以像调用方法一样使用变量调用传递给它的方法


您可以在线阅读更多内容,例如:

委托只是一种类型。对于您习惯的类型(如
int
string
等),当您想要使用它们时,您可以使用框架中的类型,也可以声明自己的类型。您可以对代理执行完全相同的操作-使用预构建的代理(如
System.Action
)或声明您自己的代理,这就是此处所做的

因此,在您的代码片段中,声明了3种类型:

public delegate bool IntPredicate(int x);
public delegate void IntAction(int x);

class IntList : List<int> { ... }
委托的原理是相同的,但是,当然,您必须传入委托类型的内容或可以转换为委托类型的内容。您有几个选择:

现有方法

如果方法的签名(即返回值和参数)与委托的签名匹配,则可以传入方法。所以,你可以这样做:

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

委托是一种类型。您可以在变量或方法参数中使用它。可以仅使用方法的名称传递方法,也可以创建匿名方法。然后,可以像调用方法一样使用变量调用传递给它的方法


你可以在网上阅读更多信息,例如:

+1非常好的解释,我自己说得再好不过了。非常好的解释!谢谢!我只想澄清一件事,看看我是否理解正确:在
Act
Filter
的范围内,函数
f(I)
p(I)
是我作为参数传递给
Act
Filter
的函数,我通过创建它们的主体来决定它们做什么(即在类的
Main
函数中)?不客气。是的,我认为您理解正确。重要的是方法
Act
Filter