专栏首页林德熙的博客C# 里面很少人知道但很好用的 Tuple 转换

C# 里面很少人知道但很好用的 Tuple 转换

小伙伴们都知道有 Tuple 但是很少有小伙伴只有原来从一个类转换为一个 Tuple 的方式如此简洁,在 C# 最新版本里面提供了一组语法糖,可以便捷给任意的类扩展转换为元组的能力

先来看看下面这段有趣的代码

我可以将 Lindexi 类解析为 (string name, string doubi) 的元组,只需要 Lindexi 存在Deconstruct方法,存在这个方法的类不需要继承任何接口,只需要方法名是 Deconstruct 参数全部都是 out 的就可以

如上面例子里面的代码

    class Lindexi
    {
        public string Name { get; } = "林德熙";
        public string Doubi { get; } = "逗比";

        public void Deconstruct(out string name, out string doubi)
        {
            name = Name;
            doubi = Doubi;
        }
    }

存在 Deconstruct 方法将会在编译的时候,通过 Roslyn 语法分析,生成有趣的辅助代码

这段代码我放在 github 欢迎小伙伴访问

这个语法糖在 Roslyn 上是如何用的?其实非常简单,上面代码其实可以分为两句代码做到

            lindexi.Deconstruct(out var v1, out var v2);
            var (name, doubi) = (v1, v2);

这里的 v1 和 v2 就是临时用的变量,通过 Roslyn 预编译可以知道这个类 lindexi 存在 Deconstruct 方法,又知道期望的 Tuple 需要几个参数,这样就能做到在将这个有趣的语法转换为原有的代码了

为什么我知道 Roslyn 是如何玩的?原因是看了 IL 代码就知道

    IL_0007: ldloc.0      // lindexi
    IL_0008: ldloca.s     V_3
    IL_000a: ldloca.s     V_4
    IL_000c: callvirt     instance void BepirquwiKedoucawji.Lindexi::Deconstruct(string&, string&)
    IL_0011: nop
    IL_0012: ldloc.3      // V_3
    IL_0013: stloc.1      // name
    IL_0014: ldloc.s      V_4
    IL_0016: stloc.2      // doubi

刚才也说到只要存在对应的方法就可以,那么扩展方法算不算?其实扩展方法也可以

    class Lindexi
    {
        public string Name { get; } = "林德熙";
        public string Doubi { get; } = "逗比";
    }

    static class Extension
    {
        public static void Deconstruct(this Lindexi lindexi, out string name, out string doubi)
        {
            name = lindexi.Name;
            doubi = lindexi.Doubi;
        }
    }

现在我修改为扩展方法了,也可以看到程序是能跑起来的,因为从 IL 代码上可以看到只有 IL_000c 这句代码更改了调用方法

    IL_0007: ldloc.0      // lindexi
    IL_0008: ldloca.s     V_3
    IL_000a: ldloca.s     V_4
    IL_000c: call         void BepirquwiKedoucawji.Extension::Deconstruct(class BepirquwiKedoucawji.Lindexi, string&, string&)
    IL_0011: nop
    IL_0012: ldloc.3      // V_3
    IL_0013: stloc.1      // name
    IL_0014: ldloc.s      V_4
    IL_0016: stloc.2      // doubi

上面代码放在 github 欢迎小伙伴访问

也就是我可以将现有的任何一个类,改造 Tuple 解析,如我可以给一个 List<int> 解析为将每个元素拼为字符串,同时返回他的元素有多少个请看代码

    static class Extension
    {
        public static void Deconstruct(this List<int> list, out string name, out int count)
        {
            name = string.Join(",", list);
            count = list.Count;
        }
    }

添加上面代码就可以愉快写出小伙伴很难看懂的代码

        static void Main(string[] args)
        {
            var (name, count) = new List<int>() { 1, 2, 3 };
            Console.WriteLine($"{name} {count}");
        }

上面代码放在 github 欢迎小伙伴访问

Deconstructing tuples and other types

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • dotnet 使用 Qpush 快速从电脑到手机推送文字

    在手机打字总不是方便,于是就有了 Qpush 这个工具,通过这个工具可以快速从电脑到手机推送文字。 但是这个工具没有找到客户端,于是我就给他写了一个库,通过这个...

    林德熙
  • C# 循环的判断会进来几次

    最近有小伙伴告诉我,在循环的判断条件只会计算一次,本金鱼不相信,于是就做了测试,本文记录我做的测试。

    林德熙
  • win10 uwp 模拟网页输入 使用 cookie

    首先创建一个 WebView ,接下来的所有输入都需要在 NavigationCompleted 之后才可以使用。

    林德熙
  • MSIL学习------从HelloWorld开始

      前段时间突然想搞搞IL语言,于是在博客园中找到了包建强前辈关于IL的文章学习,并且在包前辈博客里看到了09年他与赵劼前辈关于是否有必要学习IL语言的争论,作...

    莫问今朝
  • .netcore如何开发以太坊区块链示例 原

    本文描述了在dotNet核心中使用像以太坊这样的区块链平台的过程。目标受众是其他想要从以太坊开始的dotNet开发者。需要了解区块链。在本文中,我们构建了一个完...

    笔阁
  • Lua中正则表达式的使用整理

    原文链接:https://blog.csdn.net/fightsyj/article/details/8361549...

    bering
  • 跨域的原因以及解决方案

    --args--disable-web-security--user-data-dir设置浏览器的启动参数,将浏览器的同源策略取消。该方式要求所用的用户进行手动...

    喜欢天文的pony站长
  • 2018-09-27#hive 表写入数据的方式

    大数据工程师-公子
  • 区块链电子发票极速版上线,中小企业注册开通仅30分钟

          疫情新增数据下降,全国各地迎来复工复产大潮,许多企业面临着“发票荒”难题和非接触服务需求。       为了让区块链电子普通发票辐射更多无开发能力...

    腾讯TrustSQL
  • 【一周简报】听云APM助力e代驾引领代驾新模式

    image.png 智选SDK一周资讯大事记,将会为您呈现过去一周最受欢迎的SDK资讯、投融资、企业活动、人物访谈和创业故事等信息。让您在最短的时间内了解最火爆...

    BestSDK

扫码关注云+社区

领取腾讯云代金券