有人能解释一下C#&#34; Func <t,t>&#34;呢?</T,T>

时间:2011-03-15 17:23:07

标签: c# func

我正在阅读Pro MVC 2书,并且有一个为HtmlHelper类创建扩展方法的示例。

这里是代码示例:

public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int,string> pageUrl)
{
    //Magic here.
}

以下是一个示例用法:

[Test]
public void Can_Generate_Links_To_Other_Pages()
{
    //Arrange: We're going to extend the Html helper class.
    //It doesn't matter if the variable we use is null            
    HtmlHelper html = null;

    PagingInfo pagingInfo = PagingInfo(){
        CurrentPage = 2,
        TotalItems = 28,
        ItemsPerPage = 10
    };

    Func<int, String> pageUrl = i => "Page" + i;

    //Act: Here's how it should format the links.
    MvcHtmlString result = html.PageLinks(pagingInfo, pageUrl);

    //Assert:
    result.ToString().ShouldEqual(@"<a href=""Page1"">1</a><a href=""Page2"">2</a><a href=""Page3"">3</a>")           

}

修改:删除了与此问题的混淆的部分。

问题是:为什么使用Func的例子?我应该什么时候使用它?什么是Func?

谢谢!

8 个答案:

答案 0 :(得分:106)

A Func<int, string>喜欢

Func<int, String> pageUrl = i => "Page" + i;

是一个委托,接受int作为其唯一参数并返回string。在此示例中,它接受名为int的{​​{1}}参数,并返回字符串i,该字符串仅将"Page" + i的标准字符串表示形式连接到字符串i

通常,"Page"接受一个类型为Func<TSource, TResult>的参数,并返回类型为TSource的参数。例如,

TResult

然后你可以说

Func<string, string> toUpper = s => s.ToUpper();

string upper = toUpper("hello, world!");

所以你可以说

Func<DateTime, int> month = d => d.Month;

答案 1 :(得分:13)

Func<int, String>表示一个回调方法,它接受int参数并返回String作为结果。

以下表达式,称为lambda expression

Func<int, String> pageUrl = i => "Page" + i;

扩展为类似的东西:

Func<int, String> pageUrl = delegate(int i)
{
    return "Page" + i;
}

答案 2 :(得分:3)

您要查询的Func<int, string>行称为lambda表达式。

Func<int, String> pageUrl = i => "Page" + i;

这一行可以描述为一个带有int参数(i)并返回字符串"Page" + i的函数;

可以重写为:

delegate(int i)
{
    return "Page" + i;
}

答案 3 :(得分:1)

因为PageLinks方法是Extension Method

在扩展方法中,第一个参数以this关键字开头,表示它是第一个参数所代表的类型的Extension方法。

Func<T1, T2>是一个委托,代表从类型T1到类型T2的转换。基本上,您的PageLinks方法会将该转换应用于int以生成string

答案 4 :(得分:1)

Func<T, TResult>:封装一个具有一个参数的方法,并返回由TResult参数指定的类型的值。 See this page for more details和例子。 : - )

答案 5 :(得分:1)

有关于此的博客文章。使用Func可以解决一些功能差异。阅读here

答案 6 :(得分:0)

我已经使用Func实现了一个where()扩展方法,请看看......

public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<Tsource> a , Func<Tsource , bool> Method )
{

    foreach ( var data in a )
    {
        //If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
        if ( Method.Invoke ( data ) )
        {
            yield return data;
        }
    }
}

您可以像使用

一样使用它
        foreach ( var item in Emps.Where ( e => e.Name == "Shiv" ).Select ( e1 => e1.Name ) )
        {
            Console.WriteLine ( item );
        }

答案 7 :(得分:0)

创建自己的

Func<int,string> myfunc; 

然后右键单击Func查看定义。你会看到它是一个委托人

public delegate TResult Func<in T, out TResult>(T arg);