Reputation: 7435
In the namespace MS.Internal
, there is a class named NamedObject
.
It has a weird block of 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;
}
I'm curious about this comment specifically:
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
How is that 'lazy'? What does it do to be lazy?
Full class from the reference source:
//----------------------------------------------------------------------------
//
// <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.
Upvotes: 55
Views: 7916
Reputation: 726539
You escape a curly brace with a curly brace, i.e. {{
produces {
, and }}
produces }
.
The {0}
in the middle is interpreted as usual - i.e. a reference to parameter at index zero.
{{ {0} }}
^^ ^^^ ^^
| | |
| | +--- Closing curly brace
| +------ Parameter reference
+---------- Opening curly brace
The end result is the value of parameter zero enclosed in curly braces:
var res = string.Format("{{{0}}}", "hello"); // produces {hello}
How is that 'lazy'?
They call it lazy with respect to this alternative "eager" implementation:
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;
}
This implementation adds curly braces right away, even though it has no idea that the name enclosed in curly braces is going to be needed.
Upvotes: 66
Reputation: 273219
How is that 'lazy'? What does it do to be lazy?
The laziness comes from the if (_name[0] != '{')
before it.
It only changes the _name
field when it is requested for the first time.
And like everybody already pointed out, String.Format("{{{0}}}", _name);
should be read as "{{ {0} }}"
or "\{ {0} \}"
. The inner {0}
is the actual field to substitute with the first argument, the outer {{
and }}
are a special notation to get single {}
Upvotes: 15
Reputation: 24903
var value = "value";
String.Format(CultureInfo.InvariantCulture, "{{{0}}}", value); // will output {value}
Upvotes: 6
Reputation: 11832
{{
and }}
just give you literal {
and }
. (Escaped curly braces)
so, if you have {{{0}}}
, and you give along foo
, the output will be {foo}
Upvotes: 10