背景知识介绍

臆想的一个场景: 拼接字符串, 要求自动包含字符串变量的名字和值, 并用":,"分割.

PS:仅仅是为了探索这2个特性的用法, 编码规范和实用性不在考虑范围内

  • input: 有参数 [a,b,c]
  • output "a:{a}, b:{b}, c:{c}"; {}中表示该参数的值.

利用字符串内插的方式实现这个场景

定义一个F方法并通过字符串内插传入需要拼接的参数, 如F($"{a}{b}{c}")

实现自定义的字符串内插处理程序

[InterpolatedStringHandler]
public ref struct MyInterpolatedStringHandler
{
DefaultInterpolatedStringHandler _default;
bool firstAppend = false;
public MyInterpolatedStringHandler(int literalLength, int formattedCount)
{
_default = new DefaultInterpolatedStringHandler(literalLength + (formattedCount * 16), formattedCount);
// 在DefaultInterpolatedStringHandler 内部初始化char buffer 大小用的计算方法是: literalLength + formattedCount*11
// 所以我们假定我们的单个参数表达式的长度是13, 然后在加固定的3个字符" , :" 一共16个字符. 所以有了(formattedCount * 16)
// 当然, 我们可以在这里吧要写入的对象传入进来(利用InterpolatedStringHandlerArgument特性), 比如说官方例子里面的Logger对象.
// 参考 https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/tutorials/interpolated-string-handler#add-more-capabilities-to-the-handler
}
public void AppendLiteral(string s)
{
_default.AppendLiteral(s); // AppendLiteral处理内插字符串中的字面量, 意思就是 `$"aa:{a}"` 中的 `aa:`是字面量
}
public void AppendFormatted<T>(T t, [CallerArgumentExpression("t")] string? tName = null)
{
// 按照我们想要的格式拼接字符串.
if (!append) _default.AppendLiteral(", ");
firstAppend = true;
_default.AppendLiteral(tName);
_default.AppendLiteral(":");
_default.AppendFormatted(t);
}
public string ToStringAndClear()
{
var s = _default.ToStringAndClear();
this = default;
return s;
}
}

实现F方法

void F(MyInterpolatedStringHandler s)=> Console.WriteLine(s.ToStringAndClear());

调用例子

int a=0;
int b=1;
string c=2;
F($"{a}{b}{c}") //output "a:0, b:1, c:2"

如果我们反编译这些代码,会看到和下面代码差不多:

public void Main()
{
int a=0;
int b=1;
string c=2; MyInterpolatedStringHandler result = new MyInterpolatedStringHandler(0, 3);
result.AppendFormatted(a, "a");
result.AppendFormatted(b, "b");
result.AppendFormatted(c, "c"); F(result);
}

总结

  • 这2个特性的更多介绍可以参考上面背景知识中给出的连接. 官方介绍很详细
  • 什么场景下适合自定义一个字符串内插程序(string interpolation handler) 可以阅读 新大纲

通过自定义字符串内插处理程序(InterpolatedStringHandler)和CallerArgumentExpression特性来实现一个好玩的场景的更多相关文章

  1. C++自定义字符串类

    //header.h #ifndef _HEADER_H #define _HEADER_H #define defaultSize 128 #include<iostream> #inc ...

  2. C# 中的字符串内插

    $ 特殊字符将字符串文本标识为内插字符串. 内插字符串是可能包含内插表达式的字符串文本. 将内插字符串解析为结果字符串时,带有内插表达式的项会替换为表达式结果的字符串表示形式. 此功能在 C# 6 及 ...

  3. struts2:遍历自定义字符串数组,遍历Action实例所引用对象中的数组

    在struts2:OGNL表达式,遍历List.Map集合:投影的使用一文中已经讲述了OGNL遍历List.Map集合等功能. 本文简单写一个遍历数组的示范程序. 1. 遍历自定义字符串数组 < ...

  4. ASP.NET之自定义异步HTTP处理程序(图文教程)

    前面我们学习了关于关于自定义同步HTTP处理程序,相信大家可能感觉有所成就,但是这种同步的机制只能对付客户访问较少的情况或者数据处理量不大的情况,而今天这篇文章就是解决同步HTTP处理程序的这个致命缺 ...

  5. java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串

    java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串 package com.zdz.test; im ...

  6. 使用js在HTML中自定义字符串格式化方法

    Python中支持字符串格式化,其基本形式如下: str = "I'm {name},{age} years old" print(str.format(name="te ...

  7. PHP 自定义字符串中的变量名解析

    PHP 自定义字符串中的变量名解析   这样一个需求:页面的 title 可以在后台自定义,自定义内容中可能包含变量,变量用 {$var} 表示, 其中 $var 为变量名 将 title 字段存入数 ...

  8. C#字符串内插-$

    1.字符串内插 $特殊字符将字符串文本标识未内插字符串,可能包含内插表达式的字符串文本. 将内插字符串解析为结果字符串,带有内插表达式的项会替换为表达式结果的字符串表示形式. 在C#6级更高版本语言中 ...

  9. Java实现 LeetCode 791 自定义字符串排序(桶排序)

    791. 自定义字符串排序 字符串S和 T 只包含小写字符.在S中,所有字符只会出现一次. S 已经根据某种规则进行了排序.我们要根据S中的字符顺序对T进行排序.更具体地说,如果S中x在y之前出现,那 ...

  10. HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

    HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipe ...

随机推荐

  1. AI大模型的技术之母 —— Attention Is All You Need —— Tansformer

    论文地址: https://arxiv.org/abs/1706.03762

  2. 外观很好看的云盘:一款开源的云盘系统 —— kodcloud

    看到一款外观十分好看的开源云盘系统: 下载地址: https://kodcloud.com/explorer/download/ 开源地址: https://github.com/kalcaddle ...

  3. (续)MindSpore计算框架如何发布训练好的模型到官方模型仓库MindSpore_Hub上 —— 对fork的MindSpore_Hub进行PR提交

    参考: https://gitee.com/mindspore/mindspore/blob/r1.2/CONTRIBUTING.md ================================ ...

  4. pytorch中神经网络的多线程数设置:torch.set_num_threads(N)

    实验室的同学一直都是在服务器上既用CPU训练神经网络也有使用GPU的,最近才发现原来在pytorch中可以通过设置  torch.set_num_threads(args.thread)  来限制CP ...

  5. Apache DolphinScheduler使用图关系解决核心链路告警问题,减轻任务运维负担!

    转载自程序员小陶 Apache DolphinScheduler 在使用过程中,肯定会有任务出现失败的情况,那么问题来了:调度任务的告警是需要人为配置的,在生产环境中,面对海量的任务,如何找到重要的任 ...

  6. 这是DDD建模最难的部分(其实很简单)

      本文书接上回<为了落地DDD,我是这样"PUA"大家的> ,欢迎关注我的同名公众号. https://mp.weixin.qq.com/s/DjC0FSWY1bgJ ...

  7. 9组-Beta冲刺-3/5

    一.基本情况(15分) 队名:不行就摆了吧 组长博客:9组-Beta冲刺-3/5 GitHub链接:https://github.com/miaohengming/studynote/tree/mai ...

  8. 代码随想录Day15

    110.平衡二叉树 (优先掌握递归) 给定一个二叉树,判断它是否是 平衡二叉树 平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1. 示例 1: 输入:root = [3,9,20,null, ...

  9. 如何判断数据库和对象存储是否被 JuiceFS 使用?

    随着使用 JuiceFS 的时间越来越长,一些用户已经用多种数据库和对象存储创建了很多的 JuiceFS 文件系统.有些是纯云端的,有些是纯本地的,有些则是本地与云端结合的.它们当中有一些是存储了文件 ...

  10. JavaScript设计模式样例九 —— 桥接模式

    桥接模式(Bridge Pattern) 定义:是用于把抽象化与实现化解耦,使得二者可以独立变化. 目的:将抽象部分与实现部分分离,使它们都可以独立的变化. 场景:实现系统可能有多个角度分类,每一种角 ...