我正在努力理解委托和lambda表达式,并正在阅读stackoverflow上的一些问题,然后登陆post,其中第二个例子in this comment让我完全了丢失。让我困惑的第一件事是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; };
}
答案 0 :(得分:1)
定义参数,只是推断出它们的类型。参数定义是=>
- 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表达式非常简单。第二个还关闭了&#34;创建者&#34;的参数。 function,表示你可以访问&#34; creator&#34;在代表的身体。这在纯粹的不可变代码中是完全安全的,但是如果你处理可变引用类型和副作用可能会很棘手 - 确保在你做任何疯狂的事情之前正确理解语义。
根据您在函数式编程方面的经验,认识到所有这些只是编译器技巧可能会有所帮助。这两个方法将编译为相当于这样的东西:
public Func<IList<T>, T> SelectionMethod<T>()
{
return new Func<IList<T>, T>(__HiddenAnonymousMethod);
}
private T __HiddenAnonymousMethod<T>(IList<T> list)
{
return list.First();
}
由于闭包,第二个例子更复杂 - 我们需要创建一个&#34;帮助对象&#34;保持被捕的当地人:
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);
}