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

问题描述 投票:2回答:2

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

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

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

// Pseudo code
$"Hello my name is {Key}", dict;

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

     var message = parameters.Aggregate(message, 
(current, parameter) => current.Replace(parameter.Key, parameter.Value.ToString()));

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

c# .net string
2个回答
5
投票

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

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

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

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

另见这个帖子:What's a good way of doing string templating in .NET?


5
投票

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

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

public string GetGreeting2(string name)
{
    return $"Hello {name}!";
}

两种方法的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  

所以你拥有的解决方案是完全有效的,而且我以前使用过的解决方案。唯一可能的改进是,如果您打算进行大量替换,如果您切换到使用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;
    }
}

并使用这样的:

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);
© www.soinside.com 2019 - 2024. All rights reserved.