我喜欢C#的新插值语法。
我想在appSettings
下的.config文件中存储一个动态字符串,并在其上应用插值。 interpolatedMessage
的预期值为"Your User Name is SnowWhite"
如果可能的话会很棒。 这将帮助我保持密钥可配置为任何组合。 (例如“SnowWhite是您的用户名”,“用户名 - SnowWhite”)
<appSettings>
<add key="userNameKey" value="Your User Name is {userName}" />
</appSettings>
答案 0 :(得分:7)
字符串插值是一种编译为字符串格式的语法糖,这意味着它需要在编译时知道所有细节。在您的情况下,您只知道运行时的字符串,因此您需要使用string format:
<appSettings>
<add key="userNameKey" value="Your User Name is {0}" />
</appSettings>
代码:
var message = string.Format(ConfigurationManager["userNameKey"], userName);
答案 1 :(得分:4)
使用插值字符串无法完成此操作。插值字符串中使用的变量应在编译时知道。但是,您可以使用string.Format
,
var result = string.Format(message, userName);
并将消息的值更改为以下值:
<add key="userNameKey" value="Your User Name is {0}" />
答案 2 :(得分:1)
插值字符串在编译时转换为等效的string.Format
。因此,在运行时检索字符串时,上述操作无效。
答案 3 :(得分:1)
我也错过了配置中更具可读性的字符串的行为。所以我在字符串上创建了扩展方法。
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;
}
}
答案 4 :(得分:0)
在这种情况下,您不能像其他人提到的那样使用插值。但是这个呢?
string userName = "SnowWhite";
var message = ConfigurationManager.AppSettings["userNameKey"];
message = message.Replace("{userName}", userName);