是否有“ String.Format”可以接受命名输入参数而不是索引占位符?

这就是我所知道的

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);
70303 次浏览

在 C # 6中,你可以使用 字符串插值:

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

正如 他的评论中提到的 道格 · 克拉特,字符串插值也支持 格式化字符串。可以通过在冒号后面指定来更改格式。下面的示例将输出一个逗号和小数点后两位的数字:

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

正如 他的回答中提到的 巴斯,字符串插值不支持模板字符串。事实上,它没有内置的支持。幸运的是,它存在于一些伟大的图书馆中。


例如,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出色的文档


胡须 也是一个很好的解决方案。

使用 C # 6,您可以使用 字符串插值直接将变量添加到字符串中。

例如:

string name = "List";
int age = 10;


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

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

如果可以分配一个局部变量,其中包含用于替换模板参数的数据,那么可以使用 C # 6.0 字符串插值特性字符串插值特性

基本原理是您可以根据输入数据执行相当高级的字符串替换逻辑。

举个简单的例子:

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

缺点:

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

(Major) advantages:

  • 它在模板替换中强制执行 编译时间检查

一个很好的开源解决方案是 胡子,它的语法几乎相同。它有两个可用的 C # 实现—— 胡子很尖小胡子

我已经与 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";

这称为 内插字符串,它基本上是一个模板字符串,其中包含表达式。

那为什么不直接换掉呢?

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

虽然没有内置的方法来实现这一点,但是您可以编写一个类来实现这一点。
这样的事情可以让你开始:

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

Note that this example does not force any parameter name convention. This means that you should be very careful picking your parameters names otherwise you might end up replacing parts of the string you didn't intend to.

如果你的项目中没有 C # 6,你可以使用 Linq 的:

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

If you want something matching the specific syntax in the question you can put together a pretty simple class based on 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);

注意,这些代码看起来很干净,比起性能,它们更容易理解。

你也可以使用 C # 6的字符串插值表达式:

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