是否有 "String.Format" 可以接受命名输入参数而不是索引占位符?
Is there a "String.Format" that can accept named input parameters instead of index placeholders?
这就是我所知道的
str = String.Format("Her name is {0} and she's {1} years old", "Lisa", "10");
但我想要类似
的东西
str = String("Her name is @name and she's @age years old");
str.addParameter(@name, "Lisa");
str.addParameter(@age, 10);
在 C# 6 中你可以使用 string interpolation:
string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} years old";
作为Doug Clutter mentioned in , string interpolation also supports format string。可以通过在冒号后指定格式来更改格式。以下示例将输出一个带逗号和 2 位小数的数字:
var str = $"Your account balance is {balance:N2}"
作为Bas mentioned in ,字符串插值不支持模板字符串。实际上,它没有对此的内置支持。幸运的是,它存在于一些很棒的图书馆中。
SmartFormat.NET 例如支持命名占位符:
Smart.Format("{Name} from {Address.City}, {Address.State}", user)
// The user object should at least be like that
public class User
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
public string State { get; set; }
}
有售
Mustache is also a great solution. Bas has described its pros well in .
在 C# 6 中,您可以使用 String Interpolation 直接将变量添加到字符串中。
例如:
string name = "List";
int age = 10;
var str = $"Her name is {name} and she's {age} years old";
注意,在字符串格式之前使用美元符号 ($
)。
如果您可以分配包含用于替换模板参数的数据的局部变量,则可以使用 C# 6.0 string interpolation feature。
基本原理是您可以根据输入数据进行相当高级的字符串替换逻辑。
简单示例:
string name = "John";
string message = $"Hello, my name is {name}."
复杂示例:
List<string> strings = ...
string summary = $"There are {strings.Count} strings. "
+ $"The average length is {strings.Select(s => s.Length).Average()}"
缺点:
- 不支持动态模板(例如来自资源文件)
(主要)优点:
- 它对您的模板替换执行编译时检查。
具有几乎相同语法的一个很好的开源解决方案是 Mustache. It has two available C# implementations from what I could find - mustache-sharp and Nustache。
我使用过 mustache-sharp
,发现它的功能不如字符串插值,但很接近。例如。您可以执行以下操作(从 github 页面中窃取)。
Hello, {{Customer.Name}}
{{#newline}}
{{#newline}}
{{#with Order}}
{{#if LineItems}}
Here is a summary of your previous order:
{{#newline}}
{{#newline}}
{{#each LineItems}}
{{ProductName}}: {{UnitPrice:C}} x {{Quantity}}
{{#newline}}
{{/each}}
{{#newline}}
Your total was {{Total:C}}.
{{#else}}
You do not have any recent purchases.
{{/if}}
{{/with}}
字符串插值是一个很好的解决方案,但它需要 C#6。
在这种情况下我使用 StringBuilder
var sb = new StringBuilder();
sb.AppendFormat("Her name is {0} ", "Lisa");
sb.AppendFormat("and she's {0} years old", "10");
// You can add more lines
string result = sb.ToString();
string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} years old";
这称为 Interpolated String,它基本上是一个模板字符串,其中包含表达式。
那为什么不直接替换呢?
string str = "Her name is @name and she's @age years old";
str = str.Replace("@name", "Lisa");
str = str.Replace("@age", "10");
没有内置方法可以做到这一点,但您可以编写一个 class 来为您完成。
这样的事情可以让你开始:
public class ParameterizedString
{
private string _BaseString;
private Dictionary<string, string> _Parameters;
public ParameterizedString(string baseString)
{
_BaseString = baseString;
_Parameters = new Dictionary<string, string>();
}
public bool AddParameter(string name, string value)
{
if(_Parameters.ContainsKey(name))
{
return false;
}
_Parameters.Add(name, value);
return true;
}
public override string ToString()
{
var sb = new StringBuilder(_BaseString);
foreach (var key in _Parameters.Keys)
{
sb.Replace(key, _Parameters[key]);
}
return sb.ToString();
}
}
请注意,此示例不强制任何参数名称约定。这意味着您应该非常小心地选择参数名称,否则您最终可能会替换掉您不想要的字符串部分。
如果您的项目中没有可用的 C#6,您可以使用 Linq 的 .Aggregate():
var str = "Her name is @name and she's @age years old";
var parameters = new Dictionary<string, object>();
parameters.Add("@name", "Lisa");
parameters.Add("@age", 10);
str = parameters.Aggregate(str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));
如果您想要与问题中的特定语法相匹配的内容,您可以根据聚合将一个非常简单的 class 放在一起:
public class StringFormatter{
public string Str {get;set;}
public Dictionary<string, object> Parameters {get;set;}
public StringFormatter(string p_str){
Str = p_str;
Parameters = new Dictionary<string, object>();
}
public void Add(string key, object val){
Parameters.Add(key, val);
}
public override string ToString(){
return Parameters.Aggregate(Str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));
}
}
可用如:
var str = new StringFormatter("Her name is @name and she's @age years old");
str.Add("@name", "Lisa");
str.Add("@age", 10);
Console.WriteLine(str);
请注意,这是一个看起来很干净的代码,旨在使性能易于理解。
您还可以将表达式与 C#6 的字符串插值结合使用:
string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} year{(age == 1 ? "" : "s")} old";
这就是我所知道的
str = String.Format("Her name is {0} and she's {1} years old", "Lisa", "10");
但我想要类似
的东西str = String("Her name is @name and she's @age years old");
str.addParameter(@name, "Lisa");
str.addParameter(@age, 10);
在 C# 6 中你可以使用 string interpolation:
string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} years old";
作为Doug Clutter mentioned in
var str = $"Your account balance is {balance:N2}"
作为Bas mentioned in
SmartFormat.NET 例如支持命名占位符:
Smart.Format("{Name} from {Address.City}, {Address.State}", user)
// The user object should at least be like that
public class User
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
public string State { get; set; }
}
有售
Mustache is also a great solution. Bas has described its pros well in
在 C# 6 中,您可以使用 String Interpolation 直接将变量添加到字符串中。
例如:
string name = "List";
int age = 10;
var str = $"Her name is {name} and she's {age} years old";
注意,在字符串格式之前使用美元符号 ($
)。
如果您可以分配包含用于替换模板参数的数据的局部变量,则可以使用 C# 6.0 string interpolation feature。
基本原理是您可以根据输入数据进行相当高级的字符串替换逻辑。
简单示例:
string name = "John";
string message = $"Hello, my name is {name}."
复杂示例:
List<string> strings = ...
string summary = $"There are {strings.Count} strings. "
+ $"The average length is {strings.Select(s => s.Length).Average()}"
缺点:
- 不支持动态模板(例如来自资源文件)
(主要)优点:
- 它对您的模板替换执行编译时检查。
具有几乎相同语法的一个很好的开源解决方案是 Mustache. It has two available C# implementations from what I could find - mustache-sharp and Nustache。
我使用过 mustache-sharp
,发现它的功能不如字符串插值,但很接近。例如。您可以执行以下操作(从 github 页面中窃取)。
Hello, {{Customer.Name}}
{{#newline}}
{{#newline}}
{{#with Order}}
{{#if LineItems}}
Here is a summary of your previous order:
{{#newline}}
{{#newline}}
{{#each LineItems}}
{{ProductName}}: {{UnitPrice:C}} x {{Quantity}}
{{#newline}}
{{/each}}
{{#newline}}
Your total was {{Total:C}}.
{{#else}}
You do not have any recent purchases.
{{/if}}
{{/with}}
字符串插值是一个很好的解决方案,但它需要 C#6。
在这种情况下我使用 StringBuilder
var sb = new StringBuilder();
sb.AppendFormat("Her name is {0} ", "Lisa");
sb.AppendFormat("and she's {0} years old", "10");
// You can add more lines
string result = sb.ToString();
string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} years old";
这称为 Interpolated String,它基本上是一个模板字符串,其中包含表达式。
那为什么不直接替换呢?
string str = "Her name is @name and she's @age years old";
str = str.Replace("@name", "Lisa");
str = str.Replace("@age", "10");
没有内置方法可以做到这一点,但您可以编写一个 class 来为您完成。
这样的事情可以让你开始:
public class ParameterizedString
{
private string _BaseString;
private Dictionary<string, string> _Parameters;
public ParameterizedString(string baseString)
{
_BaseString = baseString;
_Parameters = new Dictionary<string, string>();
}
public bool AddParameter(string name, string value)
{
if(_Parameters.ContainsKey(name))
{
return false;
}
_Parameters.Add(name, value);
return true;
}
public override string ToString()
{
var sb = new StringBuilder(_BaseString);
foreach (var key in _Parameters.Keys)
{
sb.Replace(key, _Parameters[key]);
}
return sb.ToString();
}
}
请注意,此示例不强制任何参数名称约定。这意味着您应该非常小心地选择参数名称,否则您最终可能会替换掉您不想要的字符串部分。
如果您的项目中没有可用的 C#6,您可以使用 Linq 的 .Aggregate():
var str = "Her name is @name and she's @age years old";
var parameters = new Dictionary<string, object>();
parameters.Add("@name", "Lisa");
parameters.Add("@age", 10);
str = parameters.Aggregate(str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));
如果您想要与问题中的特定语法相匹配的内容,您可以根据聚合将一个非常简单的 class 放在一起:
public class StringFormatter{
public string Str {get;set;}
public Dictionary<string, object> Parameters {get;set;}
public StringFormatter(string p_str){
Str = p_str;
Parameters = new Dictionary<string, object>();
}
public void Add(string key, object val){
Parameters.Add(key, val);
}
public override string ToString(){
return Parameters.Aggregate(Str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));
}
}
可用如:
var str = new StringFormatter("Her name is @name and she's @age years old");
str.Add("@name", "Lisa");
str.Add("@age", 10);
Console.WriteLine(str);
请注意,这是一个看起来很干净的代码,旨在使性能易于理解。
您还可以将表达式与 C#6 的字符串插值结合使用:
string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} year{(age == 1 ? "" : "s")} old";