有没有一个“String.Format”,可以接受命名input参数,而不是索引占位符?

这是我所知道的

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插值 :

 string name = "Lisa"; int age = 20; string str = $"Her name is {name} and she's {age} years old"; 

正如Doug Clutter在他的评论中提到的那样,string插值也支持格式string 。 可以通过在冒号后指定格式来改变格式。 以下示例将输出一个逗号和2位小数的数字:

 var str = $"Your account balance is {balance:N2}" 

正如Bas在他的回答中所提到的,string插值不支持模板string。 其实,它并没有build立在这方面的支持。 幸运的是它存在于一些伟大的图书馆。


例如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; } } 

它在NuGet上可用。


小胡子也是一个很好的解决scheme。 Bas在他的回答中描述了它的优点。

如果您可以分配包含用于replace模板参数的数据的本地variables,则可以使用C#6.0 string插值function 。

基本原理是可以根据input数据做相当先进的stringreplace逻辑。

简单的例子:

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

缺点:

  • 不支持dynamic模板(例如来自资源文件)

(主要)优势:

  • 它会对您的模板replace执行编译时检查

有一个很好的开放源码解决scheme,语法几乎相同,是胡须 。 它有两个可用的C#实现,从我能find的 – mustache-sharp和Nustache 。

我一直在mustache-sharp ,发现它没有像string插值一样的权力,但接近。 例如,你可以做以下(从它的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,您可以使用string插值直接将variables添加到string中。

例如:

 string name = "List"; int age = 10; var str = $"Her name is {name} and she's {age} years old"; 

请注意,在string格式之前使用美元符号( $ )。

那么为什么不只是replace?

 string str = "Her name is @name and she's @age years old"; str = str.Replace("@name", "Lisa"); str = str.Replace("@age", "10"); 

如果您的项目中没有可用的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())); 

如果你想在问题中匹配特定语法的东西,你可以把基于Aggregate的一个非常简单的类放在一起:

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

请注意,这是一个干净的代码,它的目标是在性能上易于理解。

没有固定的方法来做到这一点,但你可以写一个能为你做的课程。
像这样的东西可以让你开始:

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

请注意,此示例不强制使用任何参数名称约定。 这意味着你应该非常小心地select你的参数名称,否则你可能会最终取代你不想要的string部分。

string插值是一个很好的解决scheme,但是它需要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"; 

这被称为插值string ,它基本上是一个包含expression式的模板string。

您也可以使用C#6的string插值来使用expression式:

 string name = "Lisa"; int age = 20; string str = $"Her name is {name} and she's {age} year{(age == 1 ? "" : "s")} old";