Можно ли создать метод расширения для форматирования строки? - PullRequest
9 голосов
/ 05 июля 2011

вопрос действительно прост. Как мы форматируем строки в C #? таким образом:

 string.Format("string goes here with placeholders like {0} {1}", firstName, lastName);

Теперь, возможно ли создать метод расширения, чтобы сделать это таким образом?

 "string goes here {0} {1}".Format(firstName, lastName);

Вот и все.

Ответы [ 9 ]

14 голосов
/ 05 июля 2011

Ну, это сложнее, чем кажется.Другие говорят, что это возможно, и я не сомневаюсь в них, но, похоже, это не так в Mono.

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

С учетом этого кода:

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

class Program
{
    public static void Main()
    {
        Console.WriteLine("string goes here {0} {1}".Format("foo", "bar"));
    }
}

Компилятор Mono (mcs 2.10.2.0) отвечает:

foo.cs (15,54): ошибка CS0176: Статический член `string.Format (string, object) 'не может быть доступен с помощью ссылки на экземпляр, квалифицируйте его каквместо этого введите имя

Конечно, вышеприведенное компилируется чисто, если метод расширения не назван Format(), но, возможно, вы действительно хотите использовать это имя.Если это так, то это невозможно, или, по крайней мере, не во всех реализациях платформы .NET.

2 голосов
/ 05 июля 2011

Да, это возможно:

public static class StringFormatExtensions {
  public static string Format(this string formatStr, params object[] args) {
    return string.Format(formatStr, args);
  }
}

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

В целом, однако, я не вижу в этом особой ценности.

2 голосов
/ 05 июля 2011

Да, вы можете.Вы всегда хотели бы убедиться, что источник не является нулевым, конечно, для краткости оставьте это.[Обновление] получается, даже если вы можете имитировать строку. Перегрузки формата для 1, 2 и 3 аргументов за кулисами. Перегрузки строки. Формат () для аргументов 1, 2 и 3 в любом случае используют перегрузку списка varg ...Так что сняли перегрузки.

public static class FormatExtension
{
    public static string Format(this string source, params object[] args)
    {
        return string.Format(source, args);
    }
}

В дополнение, пока мы показываем, что это возможно, будьте осторожны с тем, что вы расширяете.Главное здесь то, что .Format () действительно имеет значение только для строк, которые имеют параметры формата.Это значительно упрощает использование string.Format (), потому что тогда аргументы - это, очевидно, то, что хочет Format () и должно иметь правильную форму.Однако наличие .Format () в качестве метода расширения может потерять некоторое значение, поскольку оно будет отображаться в любой строке независимо от того, действительно ли форматирование действительно допустимо для нее или нет.Просто незначительный момент.

1 голос
/ 06 июля 2011

Вы всегда должны передавать IFormatProvider в String.Format, например CultureInfo.InvariantCulture.

. Мне нравится использовать этот набор методов расширения:

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

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

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

Использование:

"{0} {1} {2}".Format(CultureInfo.InvariantCulture, "A", "B", "C");

"{0} {1} {2}".FormatInvariant("A", "B", "C");

"{0} {1} {2}".FormatCurrent("A", "B", "C");
1 голос
/ 05 июля 2011

уверен ...

public static class StringExtensions
{
    public static string FormatThis(this string format, params object[] args)
    {
        return string.Format(format, args);
    }
}
1 голос
/ 05 июля 2011

Да.

public static string Format(this string str, string firstItem, string secondItem)
{
    return string.Format(str, firstItem, secondItem);
}

Кстати, этот метод должен принадлежать к классам public и static.

0 голосов
/ 23 мая 2017

Да, как все говорили выше.Но новый предпочтительный способ должен быть:

$"string goes here {firstName} {lastName}";
0 голосов
/ 04 марта 2017

Да, это возможно:

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

и следует использовать, как показано ниже:

Console.WriteLine("format string {0} {1}".Format((object)"foo", "bar"));
0 голосов
/ 05 июля 2011
("string goes here {0} {1}").Format(firstName, lastName);

Да, вы можете. Но какую цель это решит?

...