web-dev-qa-db-ja.com

string.Formatの{{{0}}}は何をしますか?

名前空間でMS.InternalNamedObjectという名前のクラスがあります。

奇妙なコードブロックがあります。

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

それはどのように「怠laz」ですか?怠zyになるとどうなりますか?


参照ソース からの完全なクラス:

//---------------------------------------------------------------------------- 
//
// <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.
55
Mafii

中括弧で中括弧をエスケープ 、つまり、{{{を生成し、}}}を生成します。

中央の{0}は通常通り解釈されます。つまり、インデックス0のパラメーターへの参照です。

{{ {0} }}
^^ ^^^ ^^
|   |  |
|   |  +--- Closing curly brace
|   +------ Parameter reference
+---------- Opening curly brace

最終結果は、中括弧で囲まれたパラメーターゼロの値です。

var res = string.Format("{{{0}}}", "hello"); // produces {hello}

それはどのように「怠laz」ですか?

彼らは、この代替の「熱心な」実装に関してそれを遅延と呼びます。

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

この実装は、中括弧で囲まれた名前が必要になるとは考えていませんが、すぐに中括弧を追加します。

66
dasblinkenlight

それはどのように「怠laz」ですか?怠zyになるとどうなりますか?

遅延は、その前のif (_name[0] != '{')に由来します。

初めて要求されたときにのみ__name_フィールドを変更します。

そして、既に指摘したように、String.Format("{{{0}}}", _name);は_"{{ {0} }}"_または_"\{ {0} \}"_と読む必要があります。内側の_{0}_は、最初の引数に置き換える実際のフィールドです。外側の_{{_と_}}_は、単一の_{}_を取得するための特別な表記法です。

15
Henk Holterman

{{および}}リテラル{および}。 (エスケープされた中括弧)

したがって、{{{0}}}、およびfooを指定すると、出力は{foo}

10
nl-x
var value = "value";
String.Format(CultureInfo.InvariantCulture, "{{{0}}}", value); // will output {value}
6
Backs