Interpolación de cadenas mediante $

El carácter $ identifica un literal de cadena como una cadena interpolada. Una cadena interpolada es un literal de cadena que puede contener expresiones de interpolación. Cuando una cadena interpolada se resuelve en una cadena de resultado, los elementos con expresiones de interpolación se reemplazan por las representaciones de cadena de los resultados de la expresión.

La interpolación de cadenas proporciona una sintaxis más legible y conveniente de dar formato a las cadenas. Es más fácil de leer que el formato compuesto de cadenas. En este ejemplo se usan ambas características para producir el mismo resultado:

var name = "Mark";
var date = DateTime.Now;

// Composite formatting:
Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
// Both calls produce the same output that is similar to:
// Hello, Mark! Today is Wednesday, it's 19:40 now.

A partir de C# 10, puede utilizar una cadena interpolada para inicializar una cadena constante. Solo puede hacerlo si todas las expresiones de interpolación dentro de la cadena interpolada también son cadenas constantes.

Estructura de una cadena interpolada

Para distinguir un literal de cadena como una cadena interpolada, antepóngale el símbolo $. No puede haber ningún espacio en blanco entre el carácter $ y el carácter " que inicia un literal de cadena.

La estructura de un elemento con una expresión de interpolación es como se muestra aquí:

{<interpolationExpression>[,<alignment>][:<formatString>]}

Los elementos entre corchetes son opcionales. En esta tabla se describe cada elemento:

Elemento Descripción
interpolationExpression Expresión que genera un resultado al que se va a aplicar formato. La representación de cadena de null es String.Empty.
alignment La expresión constante cuyo valor define el número mínimo de caracteres en la representación de cadena del resultado de la expresión. Si es positivo, la representación de cadena está alineada a la derecha; si es negativo, está alineada a la izquierda. Para más información, vea la sección Alignment (Componente) del tema Formatos compuestos.
formatString Cadena de formato compatible con el tipo de resultado de la expresión. Para más información, vea la sección Format String (Componente) del tema Formatos compuestos.

En el ejemplo siguiente, se usan componentes opcionales de formato que se han descrito anteriormente:

Console.WriteLine($"|{"Left",-7}|{"Right",7}|");

const int FieldWidthRightAligned = 20;
Console.WriteLine($"{Math.PI,FieldWidthRightAligned} - default formatting of the pi number");
Console.WriteLine($"{Math.PI,FieldWidthRightAligned:F3} - display only three decimal digits of the pi number");
// Output is:
// |Left   |  Right|
//     3.14159265358979 - default formatting of the pi number
//                3.142 - display only three decimal digits of the pi number

A partir de C# 11, puede usar nuevas líneas dentro de una expresión de interpolación para que el código de la expresión sea más legible. En el ejemplo siguiente se muestra cómo las nuevas líneas pueden mejorar la legibilidad de una expresión que implica la coincidencia de patrones:

string message = $"The usage policy for {safetyScore} is {
    safetyScore switch
    {
        > 90 => "Unlimited usage",
        > 80 => "General usage, with daily safety check",
        > 70 => "Issues must be addressed within 1 week",
        > 50 => "Issues must be addressed within 1 day",
        _ => "Issues must be addressed before continued use",
    }
    }";

Literales de cadena sin procesar interpolados

A partir de C# 11, puede usar un literal de cadena sin formato interpolado, como se muestra en el ejemplo siguiente:

int X = 2;
int Y = 3;

var pointMessage = $"""The point "{X}, {Y}" is {Math.Sqrt(X * X + Y * Y):F3} from the origin""";

Console.WriteLine(pointMessage);
// Output is:
// The point "2, 3" is 3.606 from the origin

Para insertar { y } caracteres en la cadena de resultado, inicie un literal de cadena sin formato interpolado con varios $ caracteres. Al hacerlo, cualquier secuencia de caracteres { o } más corta que el número de $ caracteres se incrusta en la cadena de resultado. Para incluir cualquier expresión de interpolación dentro de esa cadena, debe usar el mismo número de llaves que el número de caracteres $, como se muestra en el ejemplo siguiente:

int X = 2;
int Y = 3;

var pointMessage = $$"""{The point {{{X}}, {{Y}}} is {{Math.Sqrt(X * X + Y * Y):F3}} from the origin}""";
Console.WriteLine(pointMessage);
// Output is:
// {The point {2, 3} is 3.606 from the origin}

En el ejemplo anterior, un literal de cadena sin formato interpolado comienza con dos $ caracteres. Por eso es necesario colocar todas las expresiones de interpolación entre llaves dobles {{ y }}. Una sola llave se inserta en una cadena de resultado. Si necesita incrustar repetidos { o } caracteres en una cadena de resultados, utilice un número de caracteres $ apropiadamente mayor para designar un literal de cadena en bruto interpolado.

Caracteres especiales

Para incluir una llave ("{" o "}") en el texto generado por una cadena interpolada, use dos llaves ("{{" o "}}"). Para más información, vea la sección Llaves de escape del tema Formatos compuestos.

Como los dos puntos (":") tienen un significado especial en un elemento de expresión de interpolación, para poder usar un operador condicional en una expresión de interpolación, incluya esa expresión entre paréntesis.

En el siguiente ejemplo se muestra cómo incluir una llave en una cadena de resultado. También se muestra cómo usar un operador condicional:

string name = "Horace";
int age = 34;
Console.WriteLine($"He asked, \"Is your name {name}?\", but didn't wait for a reply :-{{");
Console.WriteLine($"{name} is {age} year{(age == 1 ? "" : "s")} old.");
// Output is:
// He asked, "Is your name Horace?", but didn't wait for a reply :-{
// Horace is 34 years old.

Una cadena literal interpolada comienza con los caracteres $ y @. Los tokens $ y @ se pueden usar en cualquier orden; tanto $@"..." como @$"..." son cadenas textuales interpoladas válidas. Para más información sobre las cadenas textuales, consulte los artículos sobre cadenas e Identificadores textuales.

Formato específico de la referencia cultural

Las cadenas interpoladas usan de forma predeterminada la referencia cultural definida actualmente por la propiedad CultureInfo.CurrentCulture en todas las operaciones de formato.

Para resolver una cadena interpolada en una cadena de resultado específica de la referencia cultural, use el String.Create(IFormatProvider, DefaultInterpolatedStringHandler) método , que está disponible a partir de .NET 6. En el siguiente ejemplo se muestra cómo hacerlo:

double speedOfLight = 299792.458;

System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("nl-NL");
string messageInCurrentCulture = $"The speed of light is {speedOfLight:N3} km/s.";

var specificCulture = System.Globalization.CultureInfo.GetCultureInfo("en-IN");
string messageInSpecificCulture = string.Create(
    specificCulture, $"The speed of light is {speedOfLight:N3} km/s.");

string messageInInvariantCulture = string.Create(
    System.Globalization.CultureInfo.InvariantCulture, $"The speed of light is {speedOfLight:N3} km/s.");

Console.WriteLine($"{System.Globalization.CultureInfo.CurrentCulture,-10} {messageInCurrentCulture}");
Console.WriteLine($"{specificCulture,-10} {messageInSpecificCulture}");
Console.WriteLine($"{"Invariant",-10} {messageInInvariantCulture}");
// Output is:
// nl-NL      The speed of light is 299.792,458 km/s.
// en-IN      The speed of light is 2,99,792.458 km/s.
// Invariant  The speed of light is 299,792.458 km/s.

En .NET 5 y versiones anteriores de .NET, use la conversión implícita de una cadena interpolada a una FormattableString instancia. A continuación, puede usar un método de instancia FormattableString.ToString(IFormatProvider) o un método estático FormattableString.Invariant para generar una cadena de resultado específica de la referencia cultural. En el siguiente ejemplo se muestra cómo hacerlo:

double speedOfLight = 299792.458;
FormattableString message = $"The speed of light is {speedOfLight:N3} km/s.";

var specificCulture = System.Globalization.CultureInfo.GetCultureInfo("en-IN");
string messageInSpecificCulture = message.ToString(specificCulture);
Console.WriteLine(messageInSpecificCulture);
// Output:
// The speed of light is 2,99,792.458 km/s.

string messageInInvariantCulture = FormattableString.Invariant(message);
Console.WriteLine(messageInInvariantCulture);
// Output is:
// The speed of light is 299,792.458 km/s.

Para más información, consulte la sección Formato personalizado con ICustomFormatter del artículo Aplicar formato a tipos en .NET.

Otros recursos

Si no está familiarizado con la interpolación de cadenas, consulte el tutorial interactivo Interpolación de cadenas en C#. También puede consultar otro tutorial sobre la interpolación de cadenas en C#. En ese tutorial se muestra el uso de cadenas interpoladas para generar cadenas con formato.

Compilación de cadenas interpoladas

A partir de C# 10 y .NET 6, el compilador comprueba si una cadena interpolada se asigna a un tipo que satisface el patrón del manejador de cadenas interpoladas. Un controlador de cadenas interpoladas es un tipo personalizado que convierte la cadena interpolada en una cadena. Cuando una cadena interpolada tiene el tipo string, se procesa mediante System.Runtime.CompilerServices.DefaultInterpolatedStringHandler. Para ver el ejemplo de un manejador personalizado de interpolación de cadenas, consulte el tutorial Escribir un manejador personalizado de interpolación de cadenas. El uso de un manejador de cadenas interpolado es un escenario avanzado, normalmente necesario por razones de rendimiento.

Nota:

Un efecto secundario de los manejadores de cadenas interpoladas es que un manejador personalizado, incluido System.Runtime.CompilerServices.DefaultInterpolatedStringHandler, puede no evaluar todas las expresiones de interpolación dentro de la cadena interpolada en todas las condiciones. Eso significa que los efectos secundarios de esas expresiones pueden no producirse.

Antes de C# 10, si una cadena interpolada tiene el tipo string, normalmente se transforma en una llamada al método String.Format . El compilador puede reemplazar String.Format por String.Concat si el comportamiento analizado es equivalente a una concatenación.

Si una cadena interpolada tiene el tipo IFormattable o FormattableString, el compilador genera una llamada al método FormattableStringFactory.Create.

Especificación del lenguaje C#

Para obtener más información, consulte la sección Expresiones de cadena interpoladas de la especificación del lenguaje C# y las siguientes especificaciones de características nuevas:

Consulte también