使用Func<T1, T2, TResult> 委托返回匿名对象

Func<T1, T2, TResult> 委托

    封装一个具有两个参数并返回 TResult 参数指定的类型值的方法。

语法

public delegate TResult Func<in T1, in T2, out TResult>(
    T1 arg1,
    T2 arg2
)
类型参数
in T1
此委托封装的方法的第一个参数类型。

该类型参数是逆变。即可以使用指定的类型或派生程度更低的类型。有关协变和逆变的更多信息,请参见泛型中的协变和逆变。
in T2
此委托封装的方法的第二个参数类型。
out TResult
此委托封装的方法的返回值类型。

该类型参数是协变。即可以使用指定的类型或派生程度更高的类型。有关协变和逆变的更多信息,请参见泛型中的协变和逆变。

参数
arg1类型:T1
此委托封装的方法的第一个参数。
arg2类型:T2
此委托封装的方法的第二个参数。

返回值
类型:TResult
此委托封装的方法的返回值。

备注

      可以使用此委托表示一种能以参数形式传递的方法,而不用显式声明自定义委托。封装的方法必须与此委托定义的方法签名相对应。也就是说,封装的方法必须具有两个均通过值传递给它的参数,并且必须返回值。

若要引用具有两个参数并返回 void 的方法(或者要在 Visual Basic 中引用被声明为 Sub 而不是被声明为 Function 的方法),请改用泛型 Action<T1, T2> 委托。

  在使用 Func<T1, T2, TResult> 委托时,不必显式定义一个封装具有两个参数的方法的委托。例如,以下代码显式声明了一个名为 ExtractMethod 的委托,并将对 ExtractWords 方法的引用分配给其委托实例。

示例

      下面的示例演示如何声明和使用 Func<T1, T2, TResult> 委托。此示例声明一个 Func<T1, T2, TResult> 变量,并将其分配给一个采用 String 值和 Int32 值作为参数的 lambda 表达式。如果 String 参数的长度等于 Int32 参数的值,则此 lambda 表达式将返回 true随后在查询中使用封装此方法的委托来筛选字符串数组中的字符串。

using System;
using System.Collections.Generic;
using System.Linq;

public class Func3Example
{
   public static void Main()
   {
      Func<String, int, bool> predicate = (str, index) => str.Length == index;

      String[] words = { "orange", "apple", "Article", "elephant", "star", "and" };
      IEnumerable<String> aWords = words.Where(predicate).Select(str => str);

      foreach (String word in aWords)
         Console.WriteLine(word);
   }
}
示例

了解完这些以后,我们来看看它的应用。
      不知道童鞋们有没有遇到这样的问题,在读取数据访问层中数据集合时,发现该方法需要返回的结果中包括对象及其外键对象时,又不想添加一个实体类来封装它,那么有什么别的好办法吗?也许您会选择用动态对象(dynamic关键字),不错,这个这确实可以解决这个问题,但是有一个弊端,且不论动态对象在运行时编译,在编写程序时,它存在一个很不方便的体验,它不能点(.)出它的属性,不免产生意外的拼写错误或是寻找-复制-黏贴的麻烦。

      那么怎么办呢?我们可以利用Func<T1, T2, TResult> 委托来帮助我们实现。

public IEnumerable<TResult> GetAllUser<TResult>(Func<User, Person, TResult> itemFactory)
        {
            var results = from u in User
                          join p in Person on u.Id equals p.uId
                          select new { User = u, Person = p };

            IList<TResult> resultItems = new List<TResult>();
            foreach (var item in results.ToList())
            {
                resultItems.Add(itemFactory(item.User, item.Person));
            }

            return resultItems;
        }
数据访问层
var query = userDao.GetAllUser((u, p) =>
                {
                    return new { u.Id, u.LoginName, pId = p.Id, p.Name };
                });
表示层调取

     此外,当然也可以自定义更多的委托,这里笔者就不详细介绍了,读者可自行尝试。

     哈哈,这样是否有帮到您呢?本人文笔粗糙简陋,请多多大虾们指教!

posted @ 2013-06-26 12:14  灰身  阅读(3262)  评论(1编辑  收藏  举报