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.
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.
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 {}
{{
et }}
vous donne juste littéralement {
et }
. (Bretelles échappées)
donc, si vous avez {{{0}}}
, et vous donnez foo
, la sortie sera {foo}
var value = "value";
String.Format(CultureInfo.InvariantCulture, "{{{0}}}", value); // will output {value}