通过自定义字符串内插处理程序(InterpolatedStringHandler)和CallerArgumentExpression特性来实现一个好玩的场景
背景知识介绍
- 什么是自定义字符串内插处理程序?
- 简单来讲就是自定义一个高性能的字符串拼接程序 通过
$"{a}{b}"的方式.
- 简单来讲就是自定义一个高性能的字符串拼接程序 通过
- 什么是CallerArgumentExpression?
- 获得传进来的参数表达式的文本形式. F(string s, [CallerArgumentExpression("s")] sExpression); F(Datetime.Now.ToString()); //sExpression is "Datetime.Now.ToString()"
臆想的一个场景: 拼接字符串, 要求自动包含字符串变量的名字和值, 并用":,"分割.
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特性来实现一个好玩的场景的更多相关文章
- C++自定义字符串类
//header.h #ifndef _HEADER_H #define _HEADER_H #define defaultSize 128 #include<iostream> #inc ...
- C# 中的字符串内插
$ 特殊字符将字符串文本标识为内插字符串. 内插字符串是可能包含内插表达式的字符串文本. 将内插字符串解析为结果字符串时,带有内插表达式的项会替换为表达式结果的字符串表示形式. 此功能在 C# 6 及 ...
- struts2:遍历自定义字符串数组,遍历Action实例所引用对象中的数组
在struts2:OGNL表达式,遍历List.Map集合:投影的使用一文中已经讲述了OGNL遍历List.Map集合等功能. 本文简单写一个遍历数组的示范程序. 1. 遍历自定义字符串数组 < ...
- ASP.NET之自定义异步HTTP处理程序(图文教程)
前面我们学习了关于关于自定义同步HTTP处理程序,相信大家可能感觉有所成就,但是这种同步的机制只能对付客户访问较少的情况或者数据处理量不大的情况,而今天这篇文章就是解决同步HTTP处理程序的这个致命缺 ...
- java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串
java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串 package com.zdz.test; im ...
- 使用js在HTML中自定义字符串格式化方法
Python中支持字符串格式化,其基本形式如下: str = "I'm {name},{age} years old" print(str.format(name="te ...
- PHP 自定义字符串中的变量名解析
PHP 自定义字符串中的变量名解析 这样一个需求:页面的 title 可以在后台自定义,自定义内容中可能包含变量,变量用 {$var} 表示, 其中 $var 为变量名 将 title 字段存入数 ...
- C#字符串内插-$
1.字符串内插 $特殊字符将字符串文本标识未内插字符串,可能包含内插表达式的字符串文本. 将内插字符串解析为结果字符串,带有内插表达式的项会替换为表达式结果的字符串表示形式. 在C#6级更高版本语言中 ...
- Java实现 LeetCode 791 自定义字符串排序(桶排序)
791. 自定义字符串排序 字符串S和 T 只包含小写字符.在S中,所有字符只会出现一次. S 已经根据某种规则进行了排序.我们要根据S中的字符顺序对T进行排序.更具体地说,如果S中x在y之前出现,那 ...
- HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipe ...
随机推荐
- python3解析wav文件获取dtmf值
操作系统 :Windows 10_x64 Python版本:3.9.2 从事FreeSwitch相关工作,大概率会遇得到DTMF,DTMF的传递方式有三种: In-band RFC2833 SIP-I ...
- 全网最适合入门的面向对象编程教程:31 Python的内置数据类型-对象Object和类型Type
全网最适合入门的面向对象编程教程:31 Python 的内置数据类型-对象 Object 和类型 Type 摘要: Python 中的对象和类型是一个非常重要的概念.在 Python 中,一切都是对象 ...
- 3.2.0 版本预告!远程日志解决 Worker 故障获取不到日志的问题
Apache DolphinScheduler 3.2.0 版本已经呼之欲出,8 月 中下旬,这个大版本就要和用户见面了.为了让大家提前了解到此版本更新的主要内容,我们已经制作了几期视频和内容做了大致 ...
- 一次生产环境mysql迁移操作(二)mysql空间释放(碎片整理)
一次生产环境mysql迁移操作(一)数据归档 一次生产环境mysql迁移操作(二)mysql空间释放(碎片整理) 上文中增加了定时归档,现在一些大表磁盘空间一直不释放,导致数据库文件越来越大.现在介绍 ...
- 短视频SDK 视频编辑SDK AE模版SDK 人体抠图SDK 绿幕抠图SDK
优势: 快速接入免费试用名称: 短视频SDK品牌: 蓝松SDK特色: 一站式视音频解决方案 杭州蓝松科技有限公司,多年来一直专注于音视频领域核心技术的研发.核心研发团队掌握的行业领先技术,目前 ...
- CentOs7.3 配置基本信息查看
1.基本信息查看(命令行) [root@localhost home]# CPU个数: [root@localhost home]# grep 'physical id' /proc/cpuinfo ...
- Ubuntu16.04使用命令行安装jdk1.8
在Ubuntu中安装jdk过于麻烦,有时设置不好可能就没有办法使用,卸载也难以卸载干净,所以这篇文章使用相对简单的命令行来安装jdk,只需简单的四个命令,省去许多麻烦,下面是方法. 进入Ubuntu打 ...
- 零基础学习人工智能—Python—Pytorch学习(九)
前言 本文主要介绍卷积神经网络的使用的下半部分. 另外,上篇文章增加了一点代码注释,主要是解释(w-f+2p)/s+1这个公式的使用. 所以,要是这篇文章的代码看不太懂,可以翻一下上篇文章. 代码实现 ...
- 一种PyInstaller中优雅的控制包大小的方法
PyInstaller会在打包时自动为我们收集一些依赖项,特别是我们在打包PyQt/PySide相关的应用时,PyInstaller会自动包含我们程序通常不需要的文件,如'tanslations'文件 ...
- C#使用泛型方法将Datatable转换成List对象集合
在项目中遇到需要将Datatable转换成对象的需求,通过dr[0]取下标这种获取,如果数据的顺序发生了改变则需要改变全部,工作量大 foreach (DataRow dr in dt.Rows) { ...