我已经看到Func<>一段时间了,我已经设法避免它(现在)。但是,现在看来,我永远无法躲避它。例如,我尝试了 Dynamic Linq,但几乎所有内容都是基于 Func<> 的。我已经尝试过我的一本书(C# 2008/Deitel&Deitel)和 MSDN,但我还没有得到它。他们都直奔主题。
- 关于 Func<> 可以说什么(几句话)
- 我可以在网络上获得一些可以让我开始处理这件事的链接吗?
感谢您的帮助
Func<>
是一个通用委托 - 它使用起来非常方便,因为您不必为每个参数/返回类型组合创建自己的委托。
早些时候,您必须编写如下内容:
public delegate long MyDelegate( int number );
public void Method( IEnumerable<int> list, MyDelegate myDelegate )
{
foreach( var number in list )
{
myDelegate( number );
}
}
您必须发布您的委托,以便用户可以正确调用您的方法。特别是当您需要一堆不同的委托时,您最终会为每个参数列表和返回类型发布一个。
和Func<>
你一起写:
public void Method( IEnumerable<int> list, Func<int, long> myDelegate )
{
foreach( var number in list )
{
myDelegate( number );
}
}
这与第一个代码示例的含义相同 -Func<int, long>
定义了一个接受一个整数参数并返回一个 long 值的委托。
当然,您也可以使用更长的参数列表:Func<int, int, bool, long>
仍然会返回一个long值,而它需要两个int和一个bool值。如果您希望委托没有返回值,则必须使用Action<>
void作为返回类型。
编辑(按要求):如何在我的示例中调用该方法:
MyDelegate
对于调用者,与or的解决方案没有区别Func<>
。在这两种情况下,他都有三个选项来调用该方法:
使用 lambda 表示法(需要 C# 3.0,可能是短方法的最佳解决方案):
Method( myList, i => i * i );
通过使用匿名方法(需要 C# 2.0):
Method( myList, delegate( int i )
{
return i * i;
} );
或者通过使用真正的方法作为参数:
Method( myList, Square );
private static long Square( int number )
{
return number * number;
}
Func<...>
是一系列委托类型,它们返回一些值并接受一些参数;例如:
Func<int,bool>
只是接受一个 int 并返回一个 bool 的东西(返回总是在最后);例如谓词:
int[] data = {1,2,3,4,5};
var odd = data.Where(i => i % 2 == 0);
Func<string>
是返回字符串的方法,例如() => "hello world";
.
Func<DateDtime, TimeSpan, DateTime>
可能是这样的(when,howLong) => when + howLong;
同样Action<...>
,也有相同的功能,但没有返回类型。
没有什么神奇之处Func<...>
——它只是一种更简单的表示委托的方式,而 a:使用泛型(对 LINQ 很有用),或者 b:不需要您查找参数是什么;如果委托类型不明确(PipeStreamImpersonationWorker
例如),则可能很难知道它需要什么;如果将其表示为可比较的Action
,则很明显它不接受任何参数并返回void
。
这可能会有所帮助。假设你每次看到Func<int, string>
你都会想:
interface IFuncIntString
{
string Invoke(int x);
}
也就是说,委托是实现该接口的对象。它有一个称为 Invoke 的方法,该方法接受一个 int 并返回一个字符串。
现在添加一个功能,您可以在通话中省略“Invoke”,您就拥有了一个代表。
Func<int>
(例如)是一种类型(以一种类型的方式string
)。所以你用它来声明变量、字段、参数等等。
它代表了一个计算,只要你问它答案就可以完成:
Func<int> f = () => DateTime.Now.Second;
// elsewhere...
Console.WriteLine( f() );
请注意如何像方法一样调用它。有许多重载版本Func
来支持不同数量的参数。最后一个类型参数是返回类型。
Func<int, string> quoteInt = n => "\"" + n + "\"";
Console.WriteLine( quoteInt(3) );
Func
是委托类型。您可以声明自己的,但更容易使用Func
. 在你想返回的地方void
,使用Action
而不是Func
. out
如果您需要或ref
参数,您只需要声明自定义委托。
将 lambda 分配给 a 时Func
,您可以引用局部变量。这是非常强大的;这意味着 aFunc
不仅仅是代码;它有数据。所以它就像一个具有单个方法的对象(从技术上讲,它是 -Invoke
调用该方法,当您调用委托时编译器会为您隐式调用该方法)。
该语法() =>
可以放在任何表达式之前,表示“现在不要这样做,推迟到以后”。它允许您初始化捕获延迟计算的委托。然后可以将语法()
放在委托之后以实际触发计算。所以 suffix()
是 prefix 的对立面() =>
。
Func<..., T> 是委托。其中 T 是返回类型,所有其他 - 输入参数。
如果您曾经在 c# 中使用过 => 运算符,并且您可能已经使用过,那么您已经使用过 Funcs。您只是没有明确声明它们。
所以,如果你写一个像
var peopleWhoLikeBlue = people.Where(person => person.FavoriteColor == "Blue");
您将 a 传递给Func<Person, bool>
Where() 方法。
如果您想罗嗦,可以像这样重写该语句:
Func<Person, bool> favoriteColorIsBlue = person => person.FavoriteColor == "Blue";
var peopleWhoLikeBlue = people.Where(favoriteColorIsBlue);
你会得到同样的结果。