【C#点点滴滴】Deconstruct解构
构造函数,是在初始化对象时,把数据传给对象。那Deconstruct正好相反,是从对象中把想要的数据返回。
下面看一个使用场景,下面是定义一个record的Order,我们可以用元数据的方式,从Order对象中把no,orderTime取出来,这是怎么做到的呢?
//Order定义成record record Order(string No, DateTime OrderTime, string Address); //使用Order var (no, orderTime, _) = new Order("T000001", DateTime.Now, "北京市海淀区"); Console.WriteLine(no); Console.WriteLine(orderTime);
其实实现很简单,只要在类内部定义一个Deconstruct的方法就可以了,下面是另一个Order为class的实例。除了基本的属性,还实现了一个Deconstruct,参数是两个out的参数,这个方法只返回No和经过简化的Goods的ID集合。这里只是给出一个例子,对于想把什么数据解构出来,以什么形式解构出来,可以根据自己的需要。同时Deconstruct可以有重载,但是,参数一样时,函数就有二义性了。【其确我觉得可以通过(string no,List<int> goodsIds)来解决二义性,但现在不好用】
class Order { public Order(string no, DateTime orderTime, string address) { No = no; OrderTime = orderTime; Address = address; } public string No { get; set; } public DateTime OrderTime { get; set; } public string Address { get; set; } public List<Goods> Goodses { get; set; } = new List<Goods>(); public void Deconstruct(out string no, out List<int> goodsIds) { no = No; goodsIds = Goodses.Select(a => a.ID).ToList(); } public void Deconstruct(out string no, out DateTime orderTime) { no = No; orderTime = OrderTime; } } var (no, goodsIds) = new Order("T000001", DateTime.Now, "北京市海淀区") { Goodses = new List<Goods> { new Goods { ID = 1, Name = "商品A", Price = 10m }, new Goods { ID = 2, Name = "商品B", Price = 15m }, } }; Console.WriteLine($"OrderNo:{no}"); foreach (var goodsId in goodsIds) { Console.WriteLine($" GoodsId:{goodsId}"); }
另外,Deconstruct可以通过扩展的方式,给一些类型增加解构功能,下面是对Exception的解构,取出Message和InnerException,当然这只是一个Demo,只提供了一条路子,具体应用可以灵活定义。
static class ExceptionExtensions { public static void Deconstruct(this Exception? exception, out string? message, out Exception? innerException) { message = exception?.Message; innerException = exception?.InnerException; } public static void Deconstruct(this Exception? exception, out string? message, out string? innerMessage, out Exception? innerInnerException) { message = exception?.Message; innerMessage = exception?.InnerException?.Message; innerInnerException = exception?.InnerException?.InnerException; } } try { throw new Exception("1级错误", new Exception("2级错误")); } catch (Exception exc) { var (msg, (innerMsg, _)) = exc; Console.WriteLine(msg); Console.WriteLine(innerMsg); }
奇奇怪怪的C#知识又增加了一点。
文章来源微信公众号
想要更快更方便的了解相关知识,可以关注微信公众号
****欢迎关注我的asp.net core系统课程****
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
2009-02-22 页面中动态画有超连接的图
2008-02-22 .net知识和学习方法系列(八)static