返回委托的方法
本文关键字:方法 返回 | 更新日期: 2023-09-27 18:01:48
我正在努力理解委托和lambda表达式,并且正在阅读stackoverflow上的一些问题,并在这个评论中的第二个例子让我完全迷失的地方找到了这篇文章。让我感到困惑的第一件事是没有在任何地方定义list参数(我知道它是返回类型的输入参数,但我发现很难理解这段代码),但我认为,通过看到如何在实践中使用这样的定义,一切都会变得更加清楚(这是我很难掌握的第二件事)。
如何在实践中使用下列方法?
public Func<IList<T>, T> SelectionMethod<T>()
{
return list => list.First();
}
public Func<float, float> QuadraticFunctionMaker(float a , float b , float c)
{
return (x) => { return a * x * x + b * x + c; };
}
参数是定义的,只是它们的类型是推断出来的。在您的示例中,参数定义分别是=>
- list
(推断为IList<T>
类型)和x
(推断为float
类型)之前的部分。
第一个委托对应的签名为:
T SomeMethod<T>(IList<T> list)
第二个是:
float SomeMethod(float x)
由于编译器知道委托的签名必须是什么,它可以自动推断所需的类型。如果您要使用老派的显式语法编写委托,它将看起来像这样:
return (Func<IList<T>, T>)(delegate (IList<T> list) { return list.First(); });
如果真的想使用显式类型,可以根据需要指定类型:
(IList<T> list) => list.First()
当你真正想要调用委托时,你需要传递参数,例如:
SelectionMethod<string>()(new List<string>())
第一个lambda表达式非常简单。第二个额外关闭了"创建者"函数的参数,这意味着您可以访问委托主体中"创建者"的参数。这在纯不可变代码中是完全安全的,但如果你要处理可变引用类型和副作用,可能会很棘手——在你对这些做任何疯狂的事情之前,确保你正确地理解了语义。
根据你的函数式编程经验,认识到所有这些都只是编译器的诡计可能会有所帮助。这两个方法将编译成类似这样的内容:
public Func<IList<T>, T> SelectionMethod<T>()
{
return new Func<IList<T>, T>(__HiddenAnonymousMethod);
}
private T __HiddenAnonymousMethod<T>(IList<T> list)
{
return list.First();
}
由于闭包的关系,第二个例子更加复杂——我们需要创建一个"helper对象"来保存捕获的局部变量:
private class __HiddenAnonymousClass
{
float a, b, c;
public __HiddenAnonymousClass(float a, float b, float c)
{
this.a = a; this.b = b; this.c = c;
}
public float __HiddenAnonymousMethod(float x)
{
return a * x * x + b * x + c;
}
}
public Func<float, float> QuadraticFunctionMaker(float a , float b , float c)
{
return new Func<float, float>
(new __HiddenAnonymousClass(a, b, c).__HiddenAnonymousMethod);
}