c# lazy-evaluation

c# - ¿Qué hace{{{0}}} en string.Format?



lazy-evaluation (4)

¿Cómo es eso ''perezoso''? ¿Qué hace ser perezoso?

La pereza proviene del if (_name[0] != ''{'') Antes que él.

Solo cambia el campo _name cuando se solicita por primera vez.

Y como todo el mundo ya señaló, String.Format("{{{0}}}", _name); debe leerse como "{{ {0} }}" o "/{ {0} /}" . El {0} interno es el campo real para sustituir con el primer argumento, el {{ y }} externo es una notación especial para obtener un solo {}

En el espacio de nombres MS.Internal , hay una clase llamada NamedObject .

Tiene un extraño bloque de código:

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

Tengo curiosidad sobre este comentario específicamente:

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

¿Cómo es eso ''perezoso''? ¿Qué hace ser perezoso?

Clase completa de la fuente de referencia :

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


Escapa de una llave con una llave , es decir, {{ produce { y }} produce } .

El {0} en el medio se interpreta como de costumbre, es decir, una referencia al parámetro en el índice cero.

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

El resultado final es el valor del parámetro cero encerrado entre llaves:

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

¿Cómo es eso ''perezoso''?

Lo llaman perezoso con respecto a esta implementación alternativa "entusiasta":

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

Esta implementación agrega llaves inmediatamente, a pesar de que no tiene idea de que el nombre encerrado entre llaves será necesario.


{{ y }} solo te da literal { y } . (Frenillos rizados escapados)

entonces, si tienes {{{0}}} , y le das a foo , el resultado será {foo}


var value = "value"; String.Format(CultureInfo.InvariantCulture, "{{{0}}}", value); // will output {value}