使用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 }; });
此外,当然也可以自定义更多的委托,这里笔者就不详细介绍了,读者可自行尝试。
哈哈,这样是否有帮到您呢?本人文笔粗糙简陋,请多多大虾们指教!
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞
· MQ 如何保证数据一致性?
· 《HelloGitHub》第 108 期