C# 里面很少人知道但很好用的 Tuple 转换
source link: https://lindexi.gitee.io/post/C-%E9%87%8C%E9%9D%A2%E5%BE%88%E5%B0%91%E4%BA%BA%E7%9F%A5%E9%81%93%E4%BD%86%E5%BE%88%E5%A5%BD%E7%94%A8%E7%9A%84-Tuple-%E8%BD%AC%E6%8D%A2.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
小伙伴们都知道有 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 欢迎小伙伴访问
本文会经常更新,请阅读原文: https://blog.lindexi.com/post/C-%E9%87%8C%E9%9D%A2%E5%BE%88%E5%B0%91%E4%BA%BA%E7%9F%A5%E9%81%93%E4%BD%86%E5%BE%88%E5%A5%BD%E7%94%A8%E7%9A%84-Tuple-%E8%BD%AC%E6%8D%A2.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者前往 CSDN 关注我的主页
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。
无盈利,不卖课,做纯粹的技术博客
以下是广告时间
推荐关注 Edi.Wang 的公众号
欢迎进入 Eleven 老师组建的 .NET 社区
以上广告全是友情推广,无盈利
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK