39

我正在阅读 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?我应该什么时候使用它?什么是功能?

谢谢!

4

8 回答 8

106

一个Func<int, string>喜欢

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

是一个委托,接受int作为其唯一参数并返回一个string. 在此示例中,它接受int带有名称的参数i并返回字符串,该字符串"Page" + i仅将标准字符串表示形式连接i到 string "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;

所以你可以说

int m = month(new DateTime(3, 15, 2011));
于 2011-03-15T17:26:38.193 回答
13

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

以下表达式,称为lambda 表达式

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

扩展到这样的东西:

Func<int, String> pageUrl = delegate(int i)
{
    return "Page" + i;
}
于 2011-03-15T17:25:36.240 回答
3

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

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

这一行可以描述为一个函数,它接受一个 int 参数 ( i) 并返回一个字符串"Page" + i

它可以重写为:

delegate(int i)
{
    return "Page" + i;
}
于 2011-03-15T17:26:33.110 回答
1

因为该PageLinks方法是一个扩展方法

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

Func<T1, T2>是代表从 typeT1到 type的转换的委托T2。所以基本上,您的PageLinks方法将应用该转换int来生​​成string.

于 2011-03-15T17:25:15.800 回答
1

Func<T, TResult>: 封装一个方法,该方法有一个参数并返回由 TResult 参数指定的类型的值。有关更多详细信息和示例,请参阅此页面。:-)

于 2011-03-15T17:27:00.253 回答
1

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

于 2014-05-29T09:38:14.133 回答
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 );
        }
于 2014-04-07T12:50:09.240 回答
0

创建你自己的

Func<int,string> myfunc; 

然后右键单击 Func 查看定义。你会看到它是一个代表underneith

public delegate TResult Func<in T, out TResult>(T arg);
于 2014-11-13T06:42:10.710 回答