天天看點

c#10:string内插處理

  string内插是指用$"日期:{DateTime.Now.ToString("yyyy年MM月dd日")}。",這種使用方式,在c#10.0時,引進了這種string内插的處理,可以寫自定義的處理程式,來提升使用體驗。具體用法見下面的代碼:

/// <summary>
/// string内插處理類型
/// </summary>
[InterpolatedStringHandler]
public ref struct TestInterpolatedStringHandler
{
    /// <summary>
    /// 建構字元串的stringbuilder
    /// </summary>
    StringBuilder builder;
    /// <summary>
    /// 兩個長度是必需的
    /// </summary>
    /// <param name="literalLength"></param>
    /// <param name="formattedCount"></param>
    public TestInterpolatedStringHandler(int literalLength, int formattedCount)
    {
        builder = new StringBuilder(literalLength);
    }

    /// <summary>
    /// 添加非格式化部分,如果被 {}分隔,會調用多次
    /// </summary>
    /// <param name="s"></param>
    public void AppendLiteral(string s)
    {
        builder.Append(s);
    }
    /// <summary>
    /// 添加格式化部分,如果有多個{},會調用多次
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    public void AppendFormatted<T>(T t)
    {
        builder.Append(t?.ToString());
    }
    internal string GetFormattedText() => builder.ToString();
}      

  那這個自定義的内插處理程式有什麼用呢?我們舉個實際的例子吧,如果把處理程式帶入參數,就能用效的來控制ApppendLiteral和AppendFormatted了。

using static System.Console;
using System.Runtime.CompilerServices;
using System.Text;

var name = "張三";
var total = 10000.0m;
var result = TestParameter("admin", $"本次向 {name} 轉賬:{total} 元");
WriteLine(result);

result = TestParameter("viewer", $"本次向 {name} 轉賬:{total} 元");
WriteLine(result);

static string TestParameter(string role, [InterpolatedStringHandlerArgument("role")] ParameterInterpolatedStringHandler handler)
{
    return handler.GetFormattedText();
}

[InterpolatedStringHandler]
public ref struct ParameterInterpolatedStringHandler
{
    /// <summary>
    /// 建構字元串的stringbuilder
    /// </summary>
    StringBuilder builder;

    string _role;
    /// <summary>
    /// 兩個長度是必需的
    /// </summary>
    /// <param name="literalLength"></param>
    /// <param name="formattedCount"></param>

    public ParameterInterpolatedStringHandler(int literalLength, int formattedCount, string role)
    {
        _role = role;
        builder = new StringBuilder(literalLength);
    }

    /// <summary>
    /// 添加非格式化部分,如果被 {}分隔,會調用多次
    /// </summary>
    /// <param name="s"></param>
    public void AppendLiteral(string s)
    {
        builder.Append(s);
    }
    /// <summary>
    /// 添加格式化部分,如果有多個{},會調用多次
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    public void AppendFormatted<T>(T t)
    {
        if (_role.ToLower() == "admin")
        {
            builder.Append(t?.ToString());
        }
        else
        {
            builder.Append("******");
        }
    }
    internal string GetFormattedText() => builder.ToString();
}