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

Ric*_*d77 20 c# func

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

  1. 关于Func <>,可以说(用几句话)
  2. 我可以在网上获得一些可以让我开始这个问题的链接吗?

谢谢你的帮助

tan*_*ius 33

Func<>是一个通用委托 - 它使用起来非常方便,因为您不必为每个参数/返回类型组合创建自己的委托.
早些时候,你必须写下这样的东西:

public delegate long MyDelegate( int number );

public void Method( IEnumerable<int> list, MyDelegate myDelegate )
{
    foreach( var number in list )
    {
        myDelegate( number );
    }
}
Run Code Online (Sandbox Code Playgroud)

您必须发布您的委托,以便用户可以正确调用您的方法.特别是当你需要一堆不同的委托时,你最终会为每个参数列表和返回类型发布一个.
有了Func<>你这样写:

public void Method( IEnumerable<int> list, Func<int, long> myDelegate )
{
    foreach( var number in list )
    {
        myDelegate( number );
    }
}
Run Code Online (Sandbox Code Playgroud)

它与第一个代码示例相同 - Func<int, long>定义一个带有一个整数参数并返回long值的委托.

当然,你也可以使用更长的参数列表:当它需要两个整数和一个bool值时Func<int, int, bool, long>仍然会返回一个值.如果您希望代理没有返回值,则必须使用,这将返回类型为void.Action<>

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

对于呼叫者,解决方案与MyDelegate或之间没有区别Func<>.在这两种情况下,他都有三个选项来调用该方法:

使用lambda表示法(需要C#3.0,可能是短方法的最佳解决方案):

Method( myList, i => i * i );
Run Code Online (Sandbox Code Playgroud)

通过使用匿名方法(需要C#2.0):

Method( myList, delegate( int i )
{
    return i * i;
} );
Run Code Online (Sandbox Code Playgroud)

或者使用真实方法作为参数:

Method( myList, Square );

private static long Square( int number )
{
    return number * number;
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 12

Func<...>是一个家庭的委托类型,返回一定的价值,并采取论证一定数量的; 例如:

  • Func<int,bool>只需要一个int并返回一个bool(返回总是在结尾); 例如谓词:

    int[] data = {1,2,3,4,5};
    var odd = data.Where(i => i % 2 == 0);
    
    Run Code Online (Sandbox Code Playgroud)
  • Func<string>是一个返回字符串的方法,例如() => "hello world";.

  • Func<DateDtime, TimeSpan, DateTime> 可能是这样的 (when,howLong) => when + howLong;

同样Action<...>,它有相同但没有返回类型.

没有什么神奇之处Func<...>- 它只是表达委托的一种更简单的方式,而a:使用泛型(对LINQ有用),或者b:不需要你查找参数是什么; 如果委托类型是模糊的(PipeStreamImpersonationWorker例如),则很难知道它需要什么; 如果将其表示为可比较的,Action则很明显它不需要参数和返回void.


Eri*_*ert 10

这可能有所帮助.假设你每次看到Func<int, string>自己都在想:

interface IFuncIntString
{
    string Invoke(int x);
}
Run Code Online (Sandbox Code Playgroud)

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

现在添加一个功能,您可以在呼叫中省略"调用",并且您自己就是一个委托.

  • 向Java程序员解释它的最佳方法;) (2认同)

Dan*_*ker 7

Func<int>(例如)是一种类型(以类型的方式string).所以你用它来声明变量,字段,参数等.

它表示可以在您要求答案时执行的计算:

Func<int> f = () => DateTime.Now.Second;

// elsewhere...

Console.WriteLine( f() );
Run Code Online (Sandbox Code Playgroud)

请注意如何像方法一样调用它.有许多重载版本Func可以支持不同数量的参数.最后一个类型参数是返回类型.

Func<int, string> quoteInt = n => "\"" + n + "\"";

Console.WriteLine( quoteInt(3) );
Run Code Online (Sandbox Code Playgroud)

Func是委托类型.您可以声明自己的,但它更容易使用Func.如果要返回void,请使用Action而不是Func.如果需要outref参数,您只需要声明自定义委托.

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

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