Сведения о вопросе

FELL

17:50, 17th August, 2020

Теги

.net   string    

Почему String.Format статичен?

Просмотров: 403   Ответов: 22

Сравнивать

String.Format("Hello {0}", "World");

с

"Hello {0}".Format("World");

Почему конструкторы .Net выбрали статический метод вместо метода экземпляра? А ты как думаешь?



  Сведения об ответе

repe

18:47, 26th August, 2020

Потому что метод Format не имеет ничего общего с текущим значением строки.

Это верно для всех строковых методов, поскольку строки .NET являются неизменяемыми.

Если бы он был нестатическим, то для начала вам понадобилась бы строка.

Это действительно так: строка формата.

Я считаю, что это просто еще один пример многих недостатков дизайна в платформе .NET (и я не имею в виду это как пламя; я все еще считаю, что фреймворк .NET превосходит большинство других фреймворков).


  Сведения об ответе

baggs

12:23, 20th August, 2020

Я на самом деле не знаю ответа, но подозреваю, что это как-то связано с аспектом прямого вызова методов на строковых литералах.

Если я правильно помню (я на самом деле не проверял это, потому что у меня нет старого IDE под рукой), ранние версии C# IDE имели проблемы с обнаружением вызовов метода против строковых литералов в IntelliSense, и это оказывает большое влияние на обнаруживаемость API. Если бы это было так, то ввод следующего текста не дал бы вам никакой помощи:

"{0}".Format(12);

Если бы вас заставили печатать

new String("{0}").Format(12);

Было бы ясно, что нет никакого преимущества в том, чтобы сделать метод Format методом экземпляра, а не статическим методом.

Библиотеки .NET были разработаны многими теми же людьми, которые дали нам MFC, и класс String, в частности, имеет сильное сходство с классом CString в MFC. MFC имеет метод формата экземпляра (который использует коды форматирования стиля printf, а не стиль фигурной скобки.NET), что очень болезненно, потому что нет такой вещи, как буквальное значение CString. Так что в кодовой базе MFC, над которой я работал, я вижу много такого:

CString csTemp = "";
csTemp.Format("Some string: %s", szFoo);

а это очень больно. (Я не говорю, что приведенный выше код-отличный способ сделать что-то даже в MFC, но, похоже, именно так большинство разработчиков проекта научились использовать CString::Format). Исходя из этого наследия, я могу представить, что дизайнеры API пытались снова избежать подобной ситуации.


  Сведения об ответе

PROGA

09:59, 28th August, 2020

Ну, я думаю, что вы должны быть довольно разборчивы в этом, но, как говорят люди, для String.Format имеет больше смысла быть статичным из-за подразумеваемой семантики. Считать:

"Hello {0}".Format("World"); // this makes it sound like Format *modifies* 
                             // the string, which is not possible as 
                             // strings are immutable.

string[] parts = "Hello World".Split(' ');    // this however sounds right, 
                                             // because it implies that you 
                                             // split an existing string into 
                                             // two *new* strings.


  Сведения об ответе

dump

06:54, 8th August, 2020

Первое, что я сделал, когда я получил обновление до VS2008 и C#3,, было сделать это

public static string F( this string format, params object[] args )
{
    return String.Format(format, args);
}

Так что теперь я могу изменить свой код с

String.Format("Hello {0}", Name);

к

"Hello {0}".F(Name);

что я и предпочел в то время. В настоящее время (2014) я не беспокоюсь, потому что это просто еще одна проблема, чтобы продолжать добавлять это в каждый случайный проект, который я создаю, или ссылку в какой-то библиотеке bag-of-utils.

А почему дизайнеры .NET выбрали именно его? Кто знает. Это кажется совершенно субъективным. Мои деньги идут на то и другое

  • Копирование Java
  • Парень, писавший ее в то время, субъективно любил ее больше.

На самом деле нет никаких других веских причин, которые я могу найти


  Сведения об ответе

SKY

08:25, 24th August, 2020

Я думаю, это потому, что формат не принимает строку как таковую, а "format string". Большинство строк равны таким вещам, как "Bob Smith" или "1010 Main St", или что у вас есть, а не "Hello {0}", как правило, вы только помещаете эти строки формата, когда пытаетесь использовать шаблон для создания другой строки, например Заводского метода, и поэтому он предоставляет себя статическому методу.


  Сведения об ответе

LIZA

04:03, 29th August, 2020

Возможно, дизайнеры .NET сделали это таким образом, потому что JAVA сделал это таким образом...

Обнимите и растяните. :)

Смотрите: http://discuss.techinterview.org/default.asp?joel.3.349728.40


  Сведения об ответе

ITSME

19:51, 23rd August, 2020

Я думаю, это потому, что это метод создателя (не уверен, что есть лучшее название). Все, что он делает, это берет то, что вы ему даете, и возвращает один строковый объект. Он не работает на существующем объекте. Если бы он был нестатическим, то для начала вам понадобилась бы строка.


  Сведения об ответе

appple

14:58, 1st August, 2020

Потому что метод Format не имеет ничего общего с текущим значением строки. Значение строки не используется. Он берет строку и возвращает ее.


  Сведения об ответе

прога

00:25, 29th August, 2020

.NET строки являются неизменяемыми
Поэтому наличие метода экземпляра не имеет абсолютно никакого смысла.

По этой логике класс string не должен иметь методов экземпляра, которые возвращают измененные копии объекта, но у него их достаточно (Trim, ToUpper и так далее). Кроме того, многие другие объекты в рамках делают то же самое.

Я согласен, что если бы они сделали его методом экземпляра, Format кажется, что это было бы плохое имя, но это не означает, что функциональность не должна быть методом экземпляра.

А почему бы и нет? Это согласуется с rest из .NET фреймворка

"Hello {0}".ToString("Orion");


  Сведения об ответе

SKY

01:34, 14th August, 2020

@Jared:

Ненагруженные, не унаследованные статические методы (например, Class.b(a,c), которые принимают экземпляр в качестве первой переменной, семантически эквивалентны вызову метода (например, a.b(c))

Нет, это не так.

(Предполагая, что он компилируется к тому же CIL, что и должно быть.)

Это твоя ошибка. Произведенное CIL отличается. Различие заключается в том, что методы-члены не могут быть вызваны для значений null , поэтому CIL вставляет проверку против значений null . Очевидно, что это не делается в статическом варианте.

Однако String.Format не допускает значений null , поэтому разработчикам пришлось вставлять проверку вручную. С этой точки зрения вариант метода членов был бы технически более совершенным.


  Сведения об ответе

SILA

18:37, 20th August, 2020

Это делается для того, чтобы избежать путаницы с .ToString() методами.

Например:

double test = 1.54d;

//string.Format pattern
string.Format("This is a test: {0:F1}", test );

//ToString pattern
"This is a test: " + test.ToString("F1");

Если бы Format был методом экземпляра для string, это могло бы вызвать путаницу, так как шаблоны отличаются.

String.Format()-это утилита для преобразования нескольких объектов в форматированную строку.

Метод экземпляра в строке что-то делает с этой строкой.

Конечно, вы могли бы это сделать:

public static string FormatInsert( this string input, params object[] args) {
    return string.Format( input, args );
}

"Hello {0}, I have {1} things.".FormatInsert( "world", 3);


  Сведения об ответе

$DOLLAR

08:20, 16th August, 2020

Методы экземпляра хороши, когда у вас есть объект, который поддерживает некоторое состояние; процесс форматирования строки не влияет на строку, с которой вы работаете (читай: не изменяет ее состояние), он создает новую строку.

С помощью методов расширения теперь вы можете получить свой торт и съесть его тоже (т. е. вы можете использовать последний синтаксис, если он помогает вам лучше спать ночью).


  Сведения об ответе

padenie

07:04, 1st August, 2020

Я думаю, что в целом лучше использовать String.Format, но я вижу смысл в том, чтобы иметь нестатическую функцию, когда у вас уже есть строка, хранящаяся в переменной, которую вы хотите "format".

Кроме того, все функции класса string не действуют на строку, а возвращают новый объект string, поскольку строки являются неизменяемыми.


  Сведения об ответе

PIRLO

16:18, 7th August, 2020

Я не знаю, почему они это сделали, но теперь это уже не имеет значения:

public static class StringExtension
{
    public static string FormatWith(this string format, params object[] args)
    {
        return String.Format(format, args);
    }
}

public class SomeClass
{
    public string SomeMethod(string name)
    {
        return "Hello, {0}".FormatWith(name);
    }
}

Это гораздо проще, IMHO.


  Сведения об ответе

COOL

20:14, 26th August, 2020

Другая причина для String.Format -это сходство с функцией printf из C. Предполагалось, что это позволит разработчикам C легче переключать языки.


  Сведения об ответе

ASER

11:35, 28th August, 2020

Большая цель дизайна для C# состояла в том, чтобы сделать переход от C/C++ к нему как можно более легким. Использование точечного синтаксиса в строковом литерале будет выглядеть очень странно для тех, кто имеет только фон C/C++, а форматирование строк-это то, что разработчик, скорее всего, сделает в первый день работы с языком. Поэтому я считаю, что они сделали его статичным, чтобы сделать его ближе к знакомой территории.


  Сведения об ответе

baggs

11:37, 1st August, 2020

Ненагруженные, не унаследованные статические методы (например, Class.b(a,c), которые принимают экземпляр в качестве первой переменной, семантически эквивалентны вызову метода (например, a.b(c)), поэтому команда платформы сделала произвольный эстетический выбор. (Предполагая, что он компилируется к тому же самому CIL, что и должно быть.) Единственный способ узнать это-спросить их, почему.

Возможно, они сделали это, чтобы держать две строки близко друг к другу лексиграфически, т. е.

String.Format("Foo {0}", "Bar");

вместо

"Foo {0}".Format("bar");

Вы хотите знать, к чему привязаны индексы; возможно, они подумали, что часть ".Format" просто добавляет шум в середине.

Интересно, что метод ToString (по крайней мере, для чисел) является противоположным: number.ToString("000") с форматной строкой справа.


  Сведения об ответе

park

04:21, 16th August, 2020

Я не вижу ничего плохого в том, что он статичен..

Семантика статического метода кажется мне гораздо более понятной. Возможно, это потому, что он примитивен. Там, где примитивы используются часто, вы хотите сделать служебный код для работы с ними как можно более легким.. Кроме того, я думаю, что семантика намного лучше с String.Format над "MyString бла-бла {0}".Format ...


  Сведения об ответе

ASER

22:34, 11th August, 2020

Я еще не пробовал его, но вы можете сделать метод расширения для того, что вы хотите. Я бы не стал этого делать, но думаю, что это сработает.

Кроме того , я нахожу String.Format() больше в соответствии с другими шаблонными статическими методами , такими как Int32.Parse(), long.TryParse() и т. д.

Вы cloud также просто используете StringBuilder , если вам нужен нестатический формат. StringBuilder.AppendFormat()


  Сведения об ответе

ASER

21:06, 1st October, 2020

String.Format должен быть статическим методом, так как строки являются неизменяемыми. Превращение его в метод экземпляра подразумевает, что вы можете использовать его для "format" или изменить значение существующей строки. Это невозможно сделать, и делать его методом экземпляра, который возвращает новую строку, было бы бессмысленно. Следовательно, это статический метод.


  Сведения об ответе

DAAA

05:10, 2nd August, 2020

String.Format принимает по крайней мере одну строку и возвращает другую строку. Ему не нужно изменять форматную строку, чтобы вернуть другую строку, поэтому это имеет мало смысла делать (игнорируя ваше форматирование). С другой стороны, было бы не так уж сложно сделать String.Format функцией-членом, за исключением того, что я не думаю, что C# допускает функции-члены const, как это делает C++. [Пожалуйста, исправьте меня и этот пост, если это так.]


  Сведения об ответе

прога

13:40, 7th August, 2020

.NET строки являются неизменяемыми

Поэтому наличие метода экземпляра не имеет абсолютно никакого смысла.

String foo = new String();

foo.Format("test {0}",1); // Makes it look like foo should be modified by the Format method. 

string newFoo = String.Format(foo, 1); // Indicates that a new string will be returned, and foo will be unaltered.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться