string.Format 上的 {{{0}}} 是做什么的?
What does {{{0}}} on string.Format do?
在命名空间 MS.Internal
中,有一个名为 NamedObject
的 class。
它有一个奇怪的代码块:
public override string ToString()
{
if (_name[0] != '{')
{
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
}
return _name;
}
我特别好奇这条评论:
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
'lazy'怎么样?懒惰有什么用?
完整 class 来自 reference source:
//----------------------------------------------------------------------------
//
// <copyright file="NamedObject.cs" company="Microsoft">
// Copyright (C) Microsoft Corporation. All rights reserved.
// </copyright>
//
// Description: Placeholder object, with a name that appears in the debugger
//
//---------------------------------------------------------------------------
using System;
using System.Globalization;
using MS.Internal.WindowsBase;
namespace MS.Internal
{
/// <summary>
/// An instance of this class can be used wherever you might otherwise use
/// "new Object()". The name will show up in the debugger, instead of
/// merely "{object}"
/// </summary>
[FriendAccessAllowed] // Built into Base, also used by Framework.
internal class NamedObject
{
public NamedObject(string name)
{
if (String.IsNullOrEmpty(name))
throw new ArgumentNullException(name);
_name = name;
}
public override string ToString()
{
if (_name[0] != '{')
{
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
}
return _name;
}
string _name;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
你escape a curly brace with a curly brace,即{{
产生{
,而}}
产生}
。
中间的 {0}
照常解释 - 即对索引零处参数的引用。
{{ {0} }}
^^ ^^^ ^^
| | |
| | +--- Closing curly brace
| +------ Parameter reference
+---------- Opening curly brace
最终结果是用花括号括起来的参数零的值:
var res = string.Format("{{{0}}}", "hello"); // produces {hello}
How is that 'lazy'?
他们称此替代方案 "eager" 实现为懒惰:
internal class NamedObject {
public NamedObject(string name) {
if (String.IsNullOrEmpty(name))
throw new ArgumentNullException(name);
if (name[0] != '{') {
// eagerly add {} around the name
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", name);
} else {
_name = name;
}
}
public override string ToString() {
return _name;
}
string _name;
}
此实现会立即添加花括号,即使它不知道将需要用花括号括起来的名称。
{{
和 }}
只是给你文字 {
和 }
。 (转义花括号)
所以,如果你有 {{{0}}}
,并且你提供 foo
,输出将是 {foo}
var value = "value";
String.Format(CultureInfo.InvariantCulture, "{{{0}}}", value); // will output {value}
How is that 'lazy'? What does it do to be lazy?
懒惰来自于它之前的if (_name[0] != '{')
。
它只在第一次请求时改变_name
字段。
正如大家已经指出的那样,String.Format("{{{0}}}", _name);
应该读作 "{{ {0} }}"
或 "\{ {0} \}"
。内部 {0}
是要替换为第一个参数的实际字段,外部 {{
和 }}
是获得单个 {}
的特殊符号
在命名空间 MS.Internal
中,有一个名为 NamedObject
的 class。
它有一个奇怪的代码块:
public override string ToString()
{
if (_name[0] != '{')
{
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
}
return _name;
}
我特别好奇这条评论:
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
'lazy'怎么样?懒惰有什么用?
完整 class 来自 reference source:
//----------------------------------------------------------------------------
//
// <copyright file="NamedObject.cs" company="Microsoft">
// Copyright (C) Microsoft Corporation. All rights reserved.
// </copyright>
//
// Description: Placeholder object, with a name that appears in the debugger
//
//---------------------------------------------------------------------------
using System;
using System.Globalization;
using MS.Internal.WindowsBase;
namespace MS.Internal
{
/// <summary>
/// An instance of this class can be used wherever you might otherwise use
/// "new Object()". The name will show up in the debugger, instead of
/// merely "{object}"
/// </summary>
[FriendAccessAllowed] // Built into Base, also used by Framework.
internal class NamedObject
{
public NamedObject(string name)
{
if (String.IsNullOrEmpty(name))
throw new ArgumentNullException(name);
_name = name;
}
public override string ToString()
{
if (_name[0] != '{')
{
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
}
return _name;
}
string _name;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
你escape a curly brace with a curly brace,即{{
产生{
,而}}
产生}
。
中间的 {0}
照常解释 - 即对索引零处参数的引用。
{{ {0} }}
^^ ^^^ ^^
| | |
| | +--- Closing curly brace
| +------ Parameter reference
+---------- Opening curly brace
最终结果是用花括号括起来的参数零的值:
var res = string.Format("{{{0}}}", "hello"); // produces {hello}
How is that 'lazy'?
他们称此替代方案 "eager" 实现为懒惰:
internal class NamedObject {
public NamedObject(string name) {
if (String.IsNullOrEmpty(name))
throw new ArgumentNullException(name);
if (name[0] != '{') {
// eagerly add {} around the name
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", name);
} else {
_name = name;
}
}
public override string ToString() {
return _name;
}
string _name;
}
此实现会立即添加花括号,即使它不知道将需要用花括号括起来的名称。
{{
和 }}
只是给你文字 {
和 }
。 (转义花括号)
所以,如果你有 {{{0}}}
,并且你提供 foo
,输出将是 {foo}
var value = "value";
String.Format(CultureInfo.InvariantCulture, "{{{0}}}", value); // will output {value}
How is that 'lazy'? What does it do to be lazy?
懒惰来自于它之前的if (_name[0] != '{')
。
它只在第一次请求时改变_name
字段。
正如大家已经指出的那样,String.Format("{{{0}}}", _name);
应该读作 "{{ {0} }}"
或 "\{ {0} \}"
。内部 {0}
是要替换为第一个参数的实际字段,外部 {{
和 }}
是获得单个 {}