前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通过自定义字符串内插处理程序(InterpolatedStringHandler)和CallerArgumentExpression特性来实现一个好玩的场景

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

作者头像
旺财的城堡
发布2022-05-11 11:32:41
4660
发布2022-05-11 11:32:41
举报
文章被收录于专栏:calvin

背景知识介绍

  • 什么是自定义字符串内插处理程序?
    • 简单来讲就是自定义一个高性能的字符串拼接程序 通过 $"{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}")

实现自定义的字符串内插处理程序
代码语言:javascript
复制
[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方法

代码语言:javascript
复制
void F(MyInterpolatedStringHandler s)=> Console.WriteLine(s.ToStringAndClear());

调用例子

代码语言:javascript
复制
int a=0;
int b=1;
string c=2;
F($"{a}{b}{c}") //output "a:0, b:1, c:2"

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

代码语言:javascript
复制
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)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景知识介绍
    • 臆想的一个场景: 拼接字符串, 要求自动包含字符串变量的名字和值, 并用":,"分割.
      • 利用字符串内插的方式实现这个场景
        • 实现F方法
          • 调用例子
            • 如果我们反编译这些代码,会看到和下面代码差不多:
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档