如何使字符串插值与字典一起工作

Unb*_*ble 2 .net c# string

我有一个字典key value pair,我需要使用String Interpolation,然后根据命名参数映射字符串.请帮我.

// code removed for brevity
var rawmessage = "Hello my name is {Name}"; // raw message
var dict= new Dictionary<string, object>();
dict.Add("{Name}", response.Name);
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这样的事情:

// Pseudo code
$"Hello my name is {Key}", dict;
Run Code Online (Sandbox Code Playgroud)

解决方案我发现到现在为止:

     var message = parameters.Aggregate(message, 
(current, parameter) => current.Replace(parameter.Key, parameter.Value.ToString()));
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我的经理真的希望我使用String Interpolation with Dictionary.我不知道如何实现这一目标.请指导我.

Gyö*_*zeg 5

它工作正常,但我的经理真的希望我使用String Interpolation with Dictionary.我不知道如何实现这一目标.

你不能这样做.C#interpolated string不是模板引擎,而是编译时功能,可转换为String.Format调用.这就是为什么你不能在常量表达式中使用字符串插值的原因.

我想使用String Interpolation将命名参数(在字典中作为Keys存在)映射到它们各自的值.但我不想使用String.Replace.有什么出路吗?

实际上你可以使用几种模板引擎(主要用于记录),所以你不需要重新发明轮子.例如,您可能会发现Serilog很有趣.

另请参见此主题:在.NET中进行字符串模板化的好方法是什么?


Dav*_*idG 5

问题是C#中的字符串插值只是一个语法糖包装器string.Format.字符串被编译为相同的代码.以此代码为例:

public string GetGreeting1(string name)
{
    return string.Format("Hello {0}!", name);
}

public string GetGreeting2(string name)
{
    return $"Hello {name}!";
}
Run Code Online (Sandbox Code Playgroud)

两种方法的IL输出完全相同:

GetGreeting1:
IL_0000:  ldstr       "Hello {0}!"
IL_0005:  ldarg.1     
IL_0006:  call        System.String.Format
IL_000B:  ret         

GetGreeting2:
IL_0000:  ldstr       "Hello {0}!"
IL_0005:  ldarg.1     
IL_0006:  call        System.String.Format
IL_000B:  ret  
Run Code Online (Sandbox Code Playgroud)

所以你拥有的解决方案是完全有效的,而且我以前使用过的解决方案.唯一可能的改进是,如果您打算进行大量替换,如果您切换到使用a,您可能会发现性能优势StringBuilder.您可能会在Nuget上找到一个可以为您完成的库,但这可能只是为了您的目的而过度杀伤.

另外,我为此做了一个扩展类.有了额外的奖励,我还添加了一个使用具有任意数量参数的对象的方法,该参数使用反射来进行替换:

public static class StringReplacementExtensions
{
    public static string Replace(this string source, Dictionary<string, string> values)
    {
        return values.Aggregate(
            source,
            (current, parameter) => current
                .Replace($"{{{parameter.Key}}}", parameter.Value));
    }

    public static string Replace(this string source, object values)
    {
        var properties = values.GetType().GetProperties();

        foreach (var property in properties)
        {
            source = source.Replace(
                $"{{{property.Name}}}", 
                property.GetValue(values).ToString());
        }

        return source;
    }
}
Run Code Online (Sandbox Code Playgroud)

并使用这样的:

var source = "Hello {name}!";

//Using Dictionary:
var dict = new Dictionary<string, string> { { "name", "David" } };
var greeting1 = source.Replace(dict);
Console.WriteLine(greeting1);

//Using an anonymous object:
var greeting2 = source.Replace(new { name = "David" });
Console.WriteLine(greeting2);
Run Code Online (Sandbox Code Playgroud)