【问题标题】:C# String Interpolation on <appSettings><appSettings> 上的 C# 字符串插值
【发布时间】:2017-07-15 12:15:13
【问题描述】:

我喜欢 C# 的新插值语法。

我想在appSettings 下的.config 文件中存储一个动态字符串并对其应用插值。 interpolatedMessage 的期望值为"Your User Name is SnowWhite"

如果可以,那就太好了。 这将帮助我保持密钥可配置为任何组合。 (例如“SnowWhite 是您的用户名”、“用户名 - SnowWhite”)

 <appSettings>
    <add key="userNameKey" value="Your User Name is {userName}" />
  </appSettings>

【问题讨论】:

    标签: c# string-interpolation


    【解决方案1】:

    字符串插值是一种编译成字符串格式的语法糖,这意味着它需要在编译时知道所有细节。在您的情况下,您只知道运行时的字符串,因此您需要使用 string format:

    <appSettings>
        <add key="userNameKey" value="Your User Name is {0}" />
    </appSettings>
    

    代码:

    var message = string.Format(ConfigurationManager["userNameKey"], userName);
    

    【讨论】:

      【解决方案2】:

      这不能使用内插字符串来完成。内插字符串中使用的变量在编译时应该是已知的。但是,您可以使用string.Format 实现您想要的,

      var result = string.Format(message, userName);
      

      并将消息的值更改为以下值:

       <add key="userNameKey" value="Your User Name is {0}" />
      

      【讨论】:

        【解决方案3】:

        内插字符串在编译时转换为string.Format 的等价物。因此,上述内容将不起作用,因为字符串是在运行时检索的。

        【讨论】:

          【解决方案4】:

          我也错过了配置中更具可读性的字符串的行为。所以我在字符串上创建了一个扩展方法。

          public static class StringExtensions
          {
              public static string Interpolate(this string self, object interpolationContext)
              {
                  var placeholders = Regex.Matches(self, @"\{(.*?)\}");
                  foreach (Match placeholder in placeholders)
                  {
                      var placeholderValue = placeholder.Value;
                      var placeholderPropertyName = placeholderValue.Replace("{", "").Replace("}", "");
                      var property = interpolationContext.GetType().GetProperty(placeholderPropertyName);
                      var value = property?.GetValue(interpolationContext)?.ToString() ?? "";
                      self = self.Replace(placeholderValue, value);
                  }
                  return self;
              }
          }
          

          并像使用它

              [Fact]
              public void Foo()
              {
                  var world = "World";
                  var someInt = 42;
                  var unused = "Not used";
          
                  //This is a normal string, it can be retrieved from config
                  var myString = "Hello {world}, this is {someInt}";
          
                  //You need to pass all local values that you may be using in your string interpolation. Pass them all as one single anonymous object.
                  var result = myString.Interpolate(new {world, someInt, unused});
          
                  result.Should().Be("Hello World, this is 42");
              }
          

          编辑: 对于点符号支持: 学分转到this answer

          public static class StringExtensions
          {
              public static string Interpolate(this string self, object interpolationContext)
              {
                  var placeholders = Regex.Matches(self, @"\{(.*?)\}");
                  foreach (Match placeholder in placeholders)
                  {
                      var placeholderValue = placeholder.Value;
                      var placeholderPropertyName = placeholderValue.Replace("{", "").Replace("}", "");
                      var value = GetPropertyValue(interpolationContext, placeholderPropertyName)?.ToString() ?? "";
                      self = self.Replace(placeholderValue, value);
                  }
                  return self;
              }
          
              public static object GetPropertyValue(object src, string propName)
              {
                  if (src == null) throw new ArgumentException("Value cannot be null.", nameof(src));
                  if (propName == null) throw new ArgumentException("Value cannot be null.", nameof(propName));
          
                  if (propName.Contains("."))
                  {
                      var temp = propName.Split(new char[] {'.'}, 2);
                      return GetPropertyValue(GetPropertyValue(src, temp[0]), temp[1]);
                  }
                  var prop = src.GetType().GetProperty(propName);
                  return prop != null ? prop.GetValue(src, null) : null;
          
              }
          }
          

          【讨论】:

            【解决方案5】:

            在这种情况下,您不能像其他人提到的那样使用插值。但是这个呢?

            string userName = "SnowWhite";
            var message = ConfigurationManager.AppSettings["userNameKey"];
            message = message.Replace("{userName}", userName);
            

            【讨论】:

              猜你喜欢
              • 2022-01-01
              • 1970-01-01
              • 2014-09-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-12-01
              • 2016-01-19
              相关资源
              最近更新 更多