我一直在玩功能<>有一段时间了,我已经设法避免它(现在)。但是,现在看来我无法永远躲避它。例如,我尝试了动态Linq,但几乎所有的东西都是按照Func <>。我试过我的一本书(C#2008/Deitel & Deitel)和MSDN,但我还没有得到它。他们全都直奔主题。简而言之,关于Func有什么可说的呢?
- 什么,可Func键<说(在几句话)>
- 我可以得到网页,可以让我开始对这个问题的一些链接?
感谢您的帮助
我一直在玩功能<>有一段时间了,我已经设法避免它(现在)。但是,现在看来我无法永远躲避它。例如,我尝试了动态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>
限定代表,它有一个整数参数,并返回一个长值。
当然你也可以使用更长的参数列表,太:Func<int, int, bool, long>
仍然会返回一个长价值,同时它有两个整数和布尔值。如果您想要一个没有返回值的代表,您将不得不使用Action<>
,它将有void作为返回类型。
EDIT(由请求):如何调用该方法在我的例子:
对于呼叫者,存在与MyDelegate
或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和返回一个布尔(返回总是在端部);例如谓词:
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 < ...,T>是委托人。 其中T是返回类型,其他所有参数都是输入参数。
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分配给Func
时,可以引用局部变量。这是非常强大的;这意味着Func
不仅仅是代码;它有数据。所以它就像一个具有单一方法的对象(在技术上它是 - 该方法被称为Invoke
,编译器在您调用委托时隐式调用该方法)。
语法() =>
可以放在任何表达式之前,以表示“现在不要执行此操作,将其延迟至以后”。它允许你初始化一个捕获延迟计算的委托。然后可以在代理之后放置语法()
以实际触发计算。所以后缀()
是前缀() =>
的一种。
+1表示一个简洁的解释。 – 2010-04-18 09:49:57
如果您曾经在c#中使用过=>运算符,并且您可能已经使用了,那么您已经使用了Funcs。你只是没有明确地宣布它们。
所以,如果你写这样
var peopleWhoLikeBlue = people.Where(person => person.FavoriteColor == "Blue");
你传递一个Func<Person, bool>
到哪里()方法的声明。
如果你想罗嗦,你可以重写像这样的语句:
Func<Person, bool> favoriteColorIsBlue = person => person.FavoriteColor == "Blue";
var peopleWhoLikeBlue = people.Where(favoriteColorIsBlue);
,你会得到相同的结果。
Jon Skeet的关于c sharp的书籍在这方面有很好的几章,为什么它对lambda函数和linq非常重要。 – 2010-04-18 10:57:29
没有什么可怕的,也没有理由避免,Func或泛型委托 - 它们只是表示采用一定数量参数的常规方法的委托。 – thecoop 2010-04-18 15:40:44
你可能想看看SO上的各种Func问题:http://stackoverflow.com/questions/tagged/func – 2010-04-18 15:51:37