web-dev-qa-db-fra.com

Que fait {{{0}}} sur string.Format?

Dans l'espace de noms MS.Internal, il existe une classe nommée NamedObject.

Il a un étrange bloc de code:

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

Je suis curieux de ce commentaire en particulier:

    // lazily add {} around the name, to avoid allocating a string 
    // until it's actually needed
    _name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);

Comment est-ce "paresseux"? Qu'est-ce que ça fait d'être paresseux?


Classe complète de la source de référence :

//---------------------------------------------------------------------------- 
//
// <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

Vous échappez à une accolade avec une accolade , c'est-à-dire {{ produit {, et }} produit }.

Le {0} au milieu est interprété comme d'habitude - c'est-à-dire une référence au paramètre à l'index zéro.

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

Le résultat final est la valeur du paramètre zéro entre accolades:

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

Comment est-ce "paresseux"?

Ils l'appellent paresseux en ce qui concerne cette implémentation alternative "désireuse":

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

Cette implémentation ajoute immédiatement des accolades, même si elle n'a aucune idée que le nom entre accolades sera nécessaire.

66
dasblinkenlight

Comment est-ce "paresseux"? Qu'est-ce que ça fait d'être paresseux?

La paresse vient de la if (_name[0] != '{') qui la précède.

Il ne modifie le champ _name Que lorsqu'il est demandé pour la première fois.

Et comme tout le monde l'a déjà souligné, String.Format("{{{0}}}", _name); doit être lu comme "{{ {0} }}" Ou "\{ {0} \}". Le {0} Intérieur est le champ réel à remplacer par le premier argument, le {{ Extérieur et }} Sont une notation spéciale pour obtenir un seul {}

15
Henk Holterman

{{ et }} vous donne juste littéralement { et }. (Bretelles échappées)

donc, si vous avez {{{0}}}, et vous donnez foo, la sortie sera {foo}

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