Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# string.Format上的{{{0}}做什么?_C#_Lazy Evaluation - Fatal编程技术网

C# string.Format上的{{{0}}做什么?

C# string.Format上的{{{0}}做什么?,c#,lazy-evaluation,C#,Lazy Evaluation,在命名空间MS.Internal中,有一个名为NamedObject的类 它有一个奇怪的代码块: 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(CultureInf

在命名空间
MS.Internal
中,有一个名为
NamedObject
的类

它有一个奇怪的代码块:

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);
那怎么会是“懒惰”?懒惰有什么用


从以下位置开始的完整类:

/--------------------------------------------------------------
//
// 
//版权所有(C)微软公司。版权所有。
//  
//
//描述:占位符对象,其名称显示在调试器中
// 
//---------------------------------------------------------------------------
使用制度;
利用制度全球化;
使用MS.Internal.WindowsBase;
名称空间MS.Internal
{
///  
///该类的实例可以在您可能使用的任何地方使用
///“new Object()”。该名称将显示在调试器中,而不是
///仅仅是“{object}”
/// 
[FriendAccessAllowed]//内置在Base中,也由Framework使用。
内部类NamedObject
{
公共名称对象(字符串名称)
{
if(String.IsNullOrEmpty(name))
抛出新的ArgumentNullException(名称);
_名称=名称;
}
公共重写字符串ToString()
{
如果(_name[0]!='{')
{
//在名称周围延迟添加{},以避免分配字符串
//直到真正需要它
_name=String.Format(CultureInfo.InvariantCulture,“{{{0}}}”,_name);
}
返回_name;
}
字符串\u名称;
}
}
//提供的文件仅供Microsoft Corporation(c)2007参考。
//版权所有(c)微软公司。保留所有权利。
你,即
{
产生
{
,而
}
产生
}

中间的<代码> { 0 } /COD>被解释为通常-即引用索引为零的参数。

{{ {0} }}
^^ ^^^ ^^
|   |  |
|   |  +--- Closing curly brace
|   +------ Parameter reference
+---------- Opening curly brace
最终结果是用大括号括起来的参数零的值:

var res = string.Format("{{{0}}}", "hello"); // produces {hello}
那怎么会是“懒惰”

他们称之为懒惰,因为这是另一种“渴望”的实现方式:

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}
“懒惰”是怎么回事?懒惰是怎么回事

懒惰来自于它前面的if(_name[0]!='{')

它仅在第一次请求时更改
\u name
字段


正如大家已经指出的,
String.Format({{{{0}}},{u name)
应该被理解为
“{{0}}}”
“{0}\}”
。内部的
{0}
是要用第一个参数替换的实际字段,外部的
{/code>和
}
符号是获取单个
}

如果它还没有完成,它只分配给_name一次,因此它被认为是懒惰的,因为只有在第一次调用
ToString()
时才会生成带花括号的字符串。你可以在这里按需阅读懒惰。@FrédéricHamidi哦,这有点狡猾hack@Mafii我知道“懒惰”这个词听起来有些贬义,但懒散的评估在任何方面都不是一种黑客行为。事实上,整个语言都是围绕着这种范式构建的。在这种情况下,
NamedObject
的实现者使用封装来保证对象的行为符合预期,同时在某些情况下节省了一些性能。@KABoissonneault这绝不意味着贬义当然。我喜欢惰性评估有多神奇——但它让我更困惑的是,当它发生的时间和原因是什么,尤其是在这种情况下。它隐含着惰性,更像是一种解决方法。这是一段很好的代码,因为它是commindet:),所以字符串在if中的contidional为true之前不会被初始化,因为编译器不知道它是否会运行?(它欺骗了编译器?@Mafii将解释替换为“非惰性”备选方案。看起来他们想尽量减少创建
NamedObject
实例的影响,以防没有人计划调用
ToString
。哦,太酷了。很好的解释,很容易理解。我甚至没想过。他们这么做真是太糟糕了(考虑到只有一个字符串)无论如何,我看不出OP发布的代码有什么不同。如果他想运行它,他可以简单地运行它。
var value = "value";
String.Format(CultureInfo.InvariantCulture, "{{{0}}}", value); // will output {value}