【C#点点滴滴】Deconstruct解构

本文介绍了C#中构造函数与Deconstruct方法的区别,展示了如何在类中使用Deconstruct方法从对象中提取特定数据,以及如何通过扩展为Exception等类型添加解构功能。
摘要由CSDN通过智能技术生成

构造函数,是在初始化对象时,把数据传给对象。那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#知识又增加了一点。7cb1bf3aec2ca023013369dd20c54192.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值