簡體   English   中英

C# 字符串插值<appsettings></appsettings>

[英]C# String Interpolation on <appSettings>

我喜歡 C# 的新插值語法。

我想在appSettings下的 my.config 文件中存儲一個動態字符串,並對其應用插值。 interpolatedMessage的預期值為"Your User Name is SnowWhite"

如果可能的話,那就太好了。 這將幫助我保持密鑰可配置為任何組合。 (例如“SnowWhite 是您的用戶名”、“用戶名 - SnowWhite”)

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

在此處輸入圖像描述

字符串插值是一種編譯為字符串格式的語法糖,這意味着它需要在編譯時知道所有細節。 在您的情況下,您只知道運行時的字符串,因此您需要使用字符串格式

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

碼:

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

使用插值字符串無法完成此操作。 插值字符串中使用的變量應在編譯時知道。 但是,你可以使用string.Format實現你想要的,

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

並將消息的值更改為以下值:

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

插值字符串在編譯時轉換為string.Format的等效字符串。 因此,上述操作無效,因為在運行時檢索字符串。

我也錯過了配置中更易讀的字符串的行為。 所以我在string上創建了一個擴展方法。

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");
    }

編輯:對於虛線符號支持:積分轉到這個答案

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;

    }
}

在這種情況下,您不能像其他人提到的那樣使用插值。 但是這個怎么樣?

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

對我來說,將內插字符串轉換為格式字符串然后使用普通的 string.format 更簡單。

private static string ConvertInterpolatedStringToFormartString(string interpolatedString)
{
   var placeholders = Regex.Matches(interpolatedString, @"\{(.*?)\}").ToArray();
   for (int i = 0; i < placeholders.Length; i++)
   {                    
       interpolatedString = interpolatedString.Replace(placeholders[i].ToString(), $"{{{i}}}");
   }
        return interpolatedString;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM