有没有办法按名称格式化字符串而不是在C#中定位?
在python中,我可以做类似这个例子的事情(从这里无耻地偷走):
>>> print '%(language)s has %(#)03d quote types.' % \ {'language': "Python", "#": 2} Python has 002 quote types.
有没有办法在C#中做到这一点?比如说:
String.Format("{some_variable}: {some_other_variable}", ...);
能够使用变量名称来做这件事会很好,但字典也是可以接受的.
没有内置的方法来处理它.
这是一种方法
string myString = "{foo} is {bar} and {yadi} is {yada}".Inject(o);
这是另一个
Status.Text = "{UserName} last logged in at {LastLoginDate}".FormatWith(user);
第三种改进方法部分基于上述两种方法,来自Phil Haack
我刚刚在我的博客上发布了一个实现:http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx
它解决了这些其他实现与大括号转义有关的一些问题.帖子有详细信息.它也可以执行DataBinder.Eval,但仍然非常快.
两者都是通过Visual Studio 2015中的新Roslyn编译器引入的.
C#6.0:
return "\{someVariable} and also \{someOtherVariable}"
要么
return $"{someVariable} and also {someOtherVariable}"
来源:C#6.0中的新功能
VB 14:
return $"{someVariable} and also {someOtherVariable}"
来源:VB 14中的新功能
值得注意的功能(在Visual Studio 2015 IDE中):
支持语法着色 - 突出显示字符串中包含的变量
支持重构 - 重命名时,字符串中包含的变量也会被重命名
实际上不仅是变量名,还支持表达式 - 例如,不仅{index}
有效,而且有效{(index + 1).ToString().Trim()}
请享用!(点击VS中的"发送微笑")
你也可以使用这样的匿名类型:
public string Format(string input, object p) { foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(p)) input = input.Replace("{" + prop.Name + "}", (prop.GetValue(p) ?? "(null)").ToString()); return input; }
当然,如果您还想解析格式化,则需要更多代码,但您可以使用此函数格式化字符串,如:
Format("test {first} and {another}", new { first = "something", another = "something else" })
似乎没有办法开箱即用.但是,实现自己的IFormatProvider
链接到IDictionary
for值看起来是可行的.
var Stuff = new Dictionary{ { "language", "Python" }, { "#", 2 } }; var Formatter = new DictionaryFormatProvider(); // Interpret {0:x} where {0}=IDictionary and "x" is hash key Console.WriteLine string.Format(Formatter, "{0:language} has {0:#} quote types", Stuff);
输出:
Python has 2 quote types
需要注意的是,您无法混合FormatProviders
,因此不能同时使用花哨的文本格式.
框架本身并没有提供这样做的方法,但你可以看看Scott Hanselman的这篇文章.用法示例:
Person p = new Person(); string foo = p.ToString("{Money:C} {LastName}, {ScottName} {BirthDate}"); Assert.AreEqual("$3.43 Hanselman, {ScottName} 1/22/1974 12:00:00 AM", foo);
James Newton-King的这段代码类似于子属性和索引,
string foo = "Top result for {Name} was {Results[0].Name}".FormatWith(student));
James的代码依赖于System.Web.UI.DataBinder来解析字符串,并且需要引用System.Web,有些人不喜欢在非Web应用程序中做.
编辑:哦,他们与匿名类型很好地工作,如果你没有准备好属性的对象:
string name = ...; DateTime date = ...; string foo = "{Name} - {Birthday}".FormatWith(new { Name = name, Birthday = date });
请参阅/sf/ask/17360801/?page=2#358259
使用链接到扩展,您可以这样写:
var str = "{foo} {bar} {baz}".Format(foo=>"foo", bar=>2, baz=>new object());
你会得到"foo 2 System.Object
".