。NET7和C11的7大自定义扩展方法
介绍
自从我开始了解扩展方法以来,我不断地发现新的可能性,让我的编码生活更轻松。 扩展方法是 SOLID完美应用 中的O ——开闭原则。 一个类应该尽可能简单,并且只在其他组件真正需要时才将属性和方法暴露给外部。
通过扩展方法,您可以为您的类实现额外的方法,而无需更改类本身! 这非常适合将类作为参数的重复方法。
实现扩展方法非常简单。 看看下面的例子: namespace System; public static class EnumerableExtensions { public static void ForEach(this IEnumerable sequence, Action action) { foreach (var item in sequence) action(item); } }
这在每个 IEnumerable(由 this 关键字引入)上实现了 ForEach() 方法,就像您从 List 类型中了解到的那样。 要访问此方法,您唯一需要做的就是添加对相应命名空间的引用,在本例中为 System。 我最常用的 7 种扩展方法
自 .NET 6 以来,Microsoft 为 IEnumerable 实现了一些扩展方法,我之前将这些方法列在了我的首选列表中,包括 DistinctBy() 和 Chunk()。 但是,从 .NET 7 开始,我仍然缺少一些非常重要的方法,尤其是处理任务(Task)集合的方法。
事不宜迟,以下是我在 .NET 7 中最常用的扩展方法: 1. TryAsync
第一种扩展方法是我最喜欢的一种。 您有多少次在刚刚创建的方法周围添加 try-catch 块,并且因为它破坏了外观而变得有点恼火? 当您的方法返回 Task 或 Task 时,这是一个非常简洁的解决方案: public static async Task TryAsync( this Task task, Action errorHandler = null ) { try { await task; return Result.Ok(); } catch (Exception ex) { if (errorHandler is not null) errorHandler(ex); return ex; } } public static async Task> TryAsync( this Task task, Action errorHandler = null ) where T : class { try { return await task; } catch (Exception ex) { if (errorHandler is not null) errorHandler(ex); return ex; } }
现在你可以这样写: var result = await GetSomethingAsync().TryAsync();
您的方法将自动包装在 try-catch 块中。 此外,您可以为其他辅助逻辑(如日志记录)提供 errorHandler。 然后可以检查这些方法返回的结果是否成功,后续您可以继续您的逻辑。
2. WhenAllAsync
集合中有多个 Task 或 Task 以正常方式处理有点不方便。 您需要调用 Task.WhenAll(tasks) 这让我有点脱离流程,因为它不是流畅的风格。 这是它的样子: public static async Task> WhenAllAsync(this IEnumerable> tasks) { if (tasks is null) throw new ArgumentNullException(nameof(tasks)); return await Task .WhenAll(tasks) .ConfigureAwait(false); } public static Task WhenAllAsync(this IEnumerable tasks) { if (tasks is null) throw new ArgumentNullException(nameof(tasks)); return Task .WhenAll(tasks); }
现在我可以方便的地处理任何任务集合: var results = await tasks.WhenAllAsync();3. WhenAllSequentialAsync
下一个扩展方法甚至可以为您节省几行代码,并让您能够逐个执行每个任务。 这在您可能不会并行执行许多任务的情况下很有用。 public static async Task> WhenAllSequentialAsync(this IEnumerable> tasks) { if (tasks is null) throw new ArgumentNullException(nameof(tasks)); var results = new List(); foreach (var task in tasks) results.Add(await task.ConfigureAwait(false)); return results; } public static async Task WhenAllSequentialAsync(this IEnumerable tasks) { if (tasks is null) throw new ArgumentNullException(nameof(tasks)); foreach (var task in tasks) await task.ConfigureAwait(false); }4. WhenAllParallelAsync
最后但同样重要的是,可能有一个用例,您可以并行执行任务,但可能有最大数量限制。 对于这种情况,我有以下扩展方法: public static async Task> WhenAllParallelAsync( this IEnumerable> tasks, int degree ) { if (tasks is null) throw new ArgumentNullException(nameof(tasks)); var results = new List(); foreach (var chunk in tasks.Chunk(degree)) { var chunkResults = await Task.WhenAll(chunk).ConfigureAwait(false); results.AddRange(chunkResults); } return results; } public static async Task WhenAllParallelAsync( this IEnumerable tasks, int degree ) { if (tasks is null) throw new ArgumentNullException(nameof(tasks)); foreach (var chunk in tasks.Chunk(degree)) await Task.WhenAll(chunk).ConfigureAwait(false); }
使用 degree 参数,您可以指定应并行执行多少个任务。 5. MapAsync
这也是一个流畅的扩展,但这次是针对单个 Task 或 Task。 public static async Task MapAsync( this Task task, Func> mapAsync ) { if (task is null) throw new ArgumentNullException(nameof(task)); if (mapAsync is null) throw new ArgumentNullException(nameof(mapAsync)); return await mapAsync(await task); } public static async Task MapAsync( this Task task, Func map ) { if (task is null) throw new ArgumentNullException(nameof(task)); if (map is null) throw new ArgumentNullException(nameof(map)); return map(await task); }
使用此扩展方法,您可以将 Task 流畅地映射到 Task,类似于 Enumerable.Select() 方法。 6. DoAsync
类似的方法是 DoAsync() ,但不是转换任务,而是可以使用任务结果执行辅助逻辑而不改变其返回值。 public static async Task DoAsync( this Task task, Func tapAsync ) { if (task is null) throw new ArgumentNullException(nameof(task)); if (tapAsync is null) throw new ArgumentNullException(nameof(tapAsync)); var res = await task; await tapAsync(res); return res; } public static async Task DoAsync( this Task task, Action tap ) { if (task is null) throw new ArgumentNullException(nameof(task)); if (tap is null) throw new ArgumentNullException(nameof(tap)); var res = await task; tap(res); return res; }7. String.Join
最后一个是我有时用于连接字符串以进行日志记录的扩展方法。 通常,您可以为此使用 string.Join() ,但同样,这并不流畅,让我无法理解。 public static string Join(this IEnumerable sequence, string separator = "") { return string.Join(separator, sequence); }缩略
技术上不是扩展方法,但对节省一些代码也很有用,以下是我的缩写方法: namespace System; public static class Abbreviations { public static IEnumerable Arr(params T[] elements) => elements; public static void Try( Action action, Action? errorHandler = null ) { try { action(); } catch (Exception ex) { if (errorHandler is not null) errorHandler(ex); } } public static Result Try( Func action, Action? errorHandler = null ) where T : class { try { return action(); } catch (Exception ex) { if (errorHandler is not null) errorHandler(ex); return ex; } } }
要轻松使用它们,您必须在根级别创建一个特殊文件(我通常将其称为 GlobalUsings.cs)并在其中放入以下行: global using static System.Abbreviations;1. Arr
Arr 方法是从现有值创建新 IEnumerable 的缩写。 通常,这将需要非常丑陋的代码,如下所示: var arr = new [] { param1, param2,... };
现在你可以这样写: var arr = Arr(param1, param2,... );
哪个看起来更漂亮? 2. Try
您有多少次只是想在一个新方法周围添加一个简单的 try-catch 块,但由于它在您的代码中占用了太多空间,所以感觉很难看? 这是一个缩写方法 Try() 的解决方案。
在最短的形式中,你可以写: Try(TestMethod);
其中 TestMethod 是一个不带任何参数的方法。 这使您能够编写极短的代码并消除那些讨厌的 try-catch 块。
对于异步方法,我建议您使用上面的扩展方法 TryAsync,因为它是流畅的风格。
当然,还有更多的可能性,您可以使用此架构并制作自己的缩写词和扩展方法。 在评论中让我知道你的想法。
我希望您发现其中一些方法有用并将它们应用到您的项目中。
谢谢阅读!
哪吒汽车张勇1530万市场最惨烈,但必须进说起来,哪吒汽车算是中国的第一代造车新势力,其前身合众新能源(为统一起见,后统称哪吒)成立的2014年,蔚来和小鹏也刚刚走进新能源市场,理想晚一年才赶上。但同行不同命,蔚小理在资本
封单!单日大涨2000元吨!大厂疯狂扩产,涨价函引爆市场!全球化工大厂相继宣布扩产投产,提振行业信心。随着涨价函发布,期盼已久的金三银四终于来了!疯狂投产!多个产业链投产扩产明显!巴斯夫科思创台积电等多个国际巨头均在2023年宣布了扩产投
44万亿元消费市场如何持续发力春暖花又开,消费热起来。在今年全国两会上,消费成了热点话题之一。政府工作报告强调把恢复和扩大消费摆在优先位置,对此,代表委员们纷纷建言献策。党的十八大以来,我们坚持实施扩大内需战略
44岁秦海璐脸垮了!面部肿胀似发面馒头,身材严重发福神似壮汉3月18日,网上流出数段秦海璐参加活动的路透,真实镜头下的她面部肿胀似发面馒头,额头鼓到要爆炸,十分恐怖。秦海璐受品牌方邀请特意现身南京为新店站街剪彩。该品牌为欢迎秦海璐的到来,专
上周黄金暴涨下周空军蓄势待发1一轮银行业危机震撼全球市场,且对美国联邦储备理事会(美联储FED)将在对抗通胀方面不那么激进的押注也得到巩固更多buerYST2硅谷银行倒闭凸显出银行面对利率大幅提高的脆弱性,瑞
天水莲馨91章节完结91旅行社接待室晴。上午。婉莲洁莲雅莲馨莲天宇热烈交谈着。洁莲昨晚飞机晚点,他们到得很晚。婉莲还是玉莲姐有先见之明,她叫我们不要等,她和三哥把他们安排住下,今早一起在接待室见个面就
34所考研自划线院校复试分数线汇总!34所考研自划线院校复试分数线汇总北京理工大学华中科技大学中国人民大学复旦大学大连理工大学重庆大学电子科技大学北京师范大学湖南大学北京航空航天大学东南大学天津大学南开大学厦门大学中
从源头把控电动自行车火灾,消防联同相关部门展开专项安全检查摘要为了有效遏制电动自行车火灾事故,从源头把控销售点是防火工作中非常重要的一项工作。为切实加强电动自行车消防安全管理监管力度,进一步规范电动自行车销售领域秩序,从源头遏制此类火灾事
重拳出击!一周内,广东4名领导干部被查,看看都有谁最近一周以来,各地各系统持续深入推进党风廉政建设和反腐败斗争,持续加大对违纪违法党员领导干部的查办力度。在这种强力反腐的高压态势下,一大批存在违纪违法问题的党员领导干部纷纷落马。其
红网夜读上坡路和下坡路,你选哪个?用声音传递温暖,欢迎收听红网夜读,我是田萌,田野的田,萌芽的萌。看过郑强教授的一段演讲视频,其中大意就是你的人生是选择过天桥,还是走地下通道?他说,大部分人都会走地下通道,为什么?
人到中年,谁不是那只戴着枷锁的猴子作者洞见muye没有什么比活着更快乐,也没有什么比活着更艰辛。前两天,看到一张照片,被深深触动了。一只中年的猴子,刚刚完成一场表演,中场休息时,戴着枷锁,靠着柱子闭目养神。在这尘世