简而言之,关于Func<>可以说什么呢?

时间:2010-04-18 09:05:14

标签: c# func

我现在一直在看 Func<> ,而且我已经设法避免它(现在)。但是,现在看起来我无法永远避开它。例如,我尝试了动态Linq,但几乎所有内容都是以Func<>表示的。我已经尝试了我的一本书(C#2008 / Deitel& Deitel)以及MSDN,但我还没有得到它。他们都直接跳入主题。

  1. 关于Func<>
  2. ,可以说(用几句话)
  3. 我可以在网上获得一些可以帮我解决这个问题的链接吗?
  4. 感谢您的帮助

7 个答案:

答案 0 :(得分:33)

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>仍会返回值,而需要两个整数和一个 bool 价值。如果您希望代表没有返回值,则必须使用Action<>,其中 void 将作为返回类型。

编辑(按要求):如何调用我的示例中的方法

对于来电者,MyDelegateFunc<>的解决方案没有区别。在这两种情况下,他都有三种方法可以调用该方法:

使用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;
}

答案 1 :(得分:12)

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

答案 2 :(得分:10)

这可能会有所帮助。假设您每次看到Func<int, string>时都想到自己:

interface IFuncIntString
{
    string Invoke(int x);
}

也就是说,委托是实现此接口的对象。它有一个名为Invoke的方法,它接受一个int并返回一个字符串。

现在添加一个功能,您可以在呼叫中省略“调用”,并且您自己就是一名代表。

答案 3 :(得分:7)

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。如果您需要outref参数,则只需声明自定义委托。

将lambda分配给Func时,可以引用局部变量。这非常强大;这意味着Func不仅仅是代码;它有数据。所以它就像一个具有单个方法的对象(从技术上讲它是 - 该方法称为Invoke,并且当您调用委托时,编译器会隐式调用该方法。)

语法() =>可以放在任何表达式之前,表示“现在不要这样做,将它延迟到以后”。它允许您初始化捕获延迟计算的委托。然后可以在委托之后放置语法()以实际触发计算。因此后缀()与前缀() =>相反。

答案 4 :(得分:3)

您可以从101 Linq Samples开始。

简而言之,Func<>是委托,其中最后一个类型参数是返回类型。

因此,Func<int,bool>是一个委托,它接受int参数并返回bool

答案 5 :(得分:1)

Func&lt; ...,T&gt;是代表。 其中T是返回类型,所有其他 - 输入参数。

答案 6 :(得分:1)

如果你曾经使用过=&gt; c#中的运算符,你可能已经使用了Funcs。你还没有明确地声明它们。

所以,如果你写一个像

这样的陈述
var peopleWhoLikeBlue = people.Where(person => person.FavoriteColor == "Blue");

您将Func<Person, bool>传递给Where()方法。

如果你想要罗嗦,你可以像这样重写那句话:

Func<Person, bool> favoriteColorIsBlue = person => person.FavoriteColor == "Blue";
var peopleWhoLikeBlue = people.Where(favoriteColorIsBlue);

你会得到相同的结果。