【问题标题】:Can someone explain what the C# "Func<T,T>" does?有人可以解释 C# "Func<T,T>" 的作用吗?
【发布时间】:2011-03-15 17:23:06
【问题描述】:

我正在阅读 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 pageUrl = i => "Page1" + i;生产线正在做。
  • 我不明白。 Func&lt;T, T&gt; 与扩展方法无关。你在问什么?
  • 你是说PageLinks的声明?第一个参数是this,即扩展方法。该参数被绑定到调用中的html 对象。
  • 注意:请忽略扩展方法位,我写错了问题。我主要想了解一下Func是什么,以及为什么这个例子选择使用它。另外,什么时候应该使用它。我提供了示例,仅用于上下文目的。
  • 注:扩展方法的引用纯粹是因为在MVC书中Func在介绍它们的章节中首次使用。

标签: c# func


【解决方案1】:

一个Func&lt;int, string&gt; 喜欢

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

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

一般来说,Func&lt;TSource, TResult&gt; 接受一个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));

【讨论】:

    【解决方案2】:

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

    以下表达式,称为lambda expression

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

    扩展为这样的:

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

    【讨论】:

      【解决方案3】:

      您查询的Func&lt;int, string&gt; 行称为 lambda 表达式。

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

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

      可以改写为:

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

      【讨论】:

      • 是否可以重载委托,比如输入是否是泛型 T where T : class?
      【解决方案4】:

      因为PageLinks 方法是Extension Method

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

      Func&lt;T1, T2&gt; 是一个委托,它表示从 T1 类型到 T2 类型的转换。所以基本上,你的 PageLinks 方法会将该转换应用到 int 以生成 string

      【讨论】:

      • 好的 - 但是 Func 部分呢?
      • 查看我的答案以获得 Func 的链接。
      【解决方案5】:

      Func&lt;T, TResult&gt;:封装一个方法,该方法有一个参数,并返回一个由 TResult 参数指定的类型的值。 See this page for more details 和示例。 :-)

      【讨论】:

        【解决方案6】:

        对此有一篇博文。使用Func,您可以解决一些功能差异。阅读here

        【讨论】:

          【解决方案7】:

          我已经使用 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 );
                  }
          

          【讨论】:

            【解决方案8】:

            创建你自己的

            Func<int,string> myfunc; 
            

            然后右击 Func 查看定义。你会看到它是一个代表在下面

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-10
              • 1970-01-01
              • 2011-03-18
              • 2020-09-10
              • 1970-01-01
              相关资源
              最近更新 更多