通过自定义字符串内插处理程序(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 ...
随机推荐
- Jax框架 —— 如何在没有GPU和TPU的设备上debug代码 —— 在CPU上使用GPU仿真设置 —— Jax框架在多卡设备上的自动并行特性的仿真体验
Jax计算框架是Google用来取代Tensorflow的新一代计算框架,这个框架使用类似pytorch的技术,但是在pytorch技术之上加入了更加强大的技术,但是这也导致该框架使用起来要比pyto ...
- 树莓派命令行配置wifi密码时如何实现密码加密(密文,非明文)
首先需要知道,树莓派系统(原生系统)的wifi配置文件为: /etc/wpa_supplicant/wpa_supplicant.conf 配置该文件时,psk属性为密码,往往我们都是使用明文来进行配 ...
- Google公司的python编码规范指南
原文地址: https://google.github.io/styleguide/pyguide.html ============================================= ...
- 使用 python flask 框架实现一个简单的抽奖系统
Flask 实现一个简易的抽奖系统 项目前置知识 目前 python主流的框架: Django .flask .Tornado 简介: 1.框架 框架? 为什莫使用框架? (前置知识讲解比较冗杂,望谅 ...
- kubeadm升级k8s之1.23.17->1.24.17
查看当前版本 [root@k8s-master31 ~]# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EX ...
- linux 操作系统下安装可视化界面
一.安装背景 1.小白一只,英文不熟.还很菜,面了几个实施,打击的体无完肤!so,人丑多读书吧. 2.安装环境: VMware + centos7 3.本着不懂就问的原则 开始了--- 二.安装前准备 ...
- BibTeX 和 BibLaTeX
BibTeX:传统的参考文献处理工具,使用 .bst 文件来定义参考文献的样式. BibLaTeX:功能更强大且更现代的工具,使用 .bbx..cbx 和 .dbx 文件来定义参考文献和引用的样式. ...
- Semantic Kernel/C#:一种通用的Function Calling方法,文末附经测试可用的大模型
Funcion Calling介绍 函数调用允许您将模型如gpt-4o与外部工具和系统连接起来.这对于许多事情都很有用,比如为AI助手赋能,或者在你的应用程序与模型之间建立深度集成. 如果您了解或者使 ...
- love music
https://music.163.com/outchain/player?type=2&id=215239
- 将.gradle下的 带hash名称文件夹中的依赖 转换为 .m2上的依赖
背景: android studio 在无法下载依赖的情况下 , 仅 使用 mavenLocal() 本地 .gradle 下有对应依赖 , .m2下没有 故将.gradle下的 带hash名称文件 ...