none
Приводят ли управляющие последовательности для фигурных скобок к какому-либо необычному поведению, о котором следует знать? RRS feed

  • Общие обсуждения

  • Решение использовать две фигурные скобки для печати единственной фигурной скобки в строке форматирования приводит к интересному результату.
    Если ограничится стандартным способом использования фигурных скобок при форматировании строк, можно написать код такого типа:

    [C#]
    int i = 42;
    string s = String.Format("{0}", i);   //prints '42'

    Однако, что если следует распечатать '{42}'? Довольно очевидным решением может показаться следующая строка кода, основанная на управляющих последоватедбностях для фигурных скобок:

    [C#]
    int i = 42;
    string s = String.Format("{{{0}}}", i);   //prints '{42}'

    Теперь хотелось бы использовать преимущества различных вариантов форматирования и указать формат для переменной. Желательно распечатать ее в формате Number («Число»), используя определитель N:

    [C#]
    int i = 42;
    string s = String.Format("{0:N}", i);   //prints '42.00'

    Двигаемся дальше. Требуется распечатать значение числа с фигурными скобками вокруг него, используя определитель формата Number. Можно ожидать, что сработает следующий прием:

    [C#]
    int i = 42;
    string s = String.Format("{{{0:N}}}", i);   //prints '{N}'

    Возникает вопрос – почему сорвалась последняя попытка? Для понимания этого необходимо знать две вещи.

    1. При предоставлении определителя формата форматирование строки требует совершить следующие действия:
      • Определить, длиннее ли определитель одного знака: если это так, следует предположить, что определитель является нестандартным форматом. Нестандартный формат будет использовать подходящие замены для вашего формата, но если неизвестно, что делать с каким-либо знаком, он просто выпишет его как литерал, найденный в формате.
      • Определить, поддерживается ли определитель из одного знака (такой как 'N' для форматирования чисел). Если это так, форматировать соответствующим образом. Если нет, выдать ArgumnetException.
    2. При попытке установить, следует ли печатать фигурную скобку, фигурные скобки обрабатываются в порядке их получения. Таким образом, в последовательности "{{{" два первых знака будут трактоваться как управляющая последовательность и будет напечатан литерал '{', а третья фигурная скобка начнет раздел форматирования. На той же основе в строке "}}}" две первые фигурных скобки воспримутся как одна закрывающаяся скобка, следовательно, в формат строки будет вписана '}' , а последняя фигурная скобка будет рассмотрена как завершающая раздел форматирования.

    Пользуясь этой информацией, можно понять, что происходит в случае "{{{0:N}}}". Первые две фигурные скобки представляют собой управляющую последовательность, после которой начинается раздел форматирования. Однако, символ закрывающейся фигурной скобки появляется перед закрытием раздела форматирования . Следовательно, в действительности отдел форматирования интерпретируется, как содержащий "0:N}".

    Теперь средство форматирования просматривает определитель формата и принимает за него "N}". Следовательно, оно интерпретирует его как созданный разработчиком нестандартный формат, а поскольку ни N, ни } ничего не значат для нестандартного числового формата, выписываются просто эти символы, а не значение переменной, на которую идет ссылка.

    Последний фрагмент не вполне понятен, но его можно сделать яснее, сравнив со следующим:

    [C#]
    int i = 42;
    string s = String.Format("{0:N!}", i);   //prints 'N!'

    То же самое происходит и в этой ситуации, но в отсутствие управляющих последовательностей все несколько яснее. Грубо говоря, определитель формата видится как "N!", что интерпретируется как нестандартный формат (длиннее одного знака), а поскольку нестандартный формат не имеет особого отношения к цифрам, то N! просто используется как значение.


    Для связи [Mail]
    • Перемещено Tagore Bandlamudi 3 октября 2010 г. 1:05 MSDN Forums consolidation (От:Форум по .NET Framework)
    18 февраля 2010 г. 11:22
    Модератор