是否可以创建一个扩展方法来格式化字符串?

时间:2011-07-05 18:34:47

标签: c# formatting extension-methods

问题很简单。我们如何在C#中格式化字符串?这样:

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

现在,是否可以通过这种方式创建扩展方法?

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

就是这样。

9 个答案:

答案 0 :(得分:14)

嗯,它看起来比它看起来更复杂。其他人说这是可能的,我不怀疑他们,但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平台的所有实现。

答案 1 :(得分:2)

是的,你可以。您总是希望验证源不为空,当然,为了简洁起见,将其留下。 [更新]虽然你可以模仿string.Format的1,2和3 args的重载,但是在幕后,对于1,2和3的args的string.Format()重载仍然使用了varg list的重载...因此删除了重载。

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

顺便说一句,虽然我们证明这是可能的,但要小心你的延伸。这里的主要内容是.Format()实际上只对具有格式参数的字符串有意义。这使得使用string.Format()变得更加清晰,因为参数显然是Format()想要的东西,并且应该是正确的形式。但是,将.Format()作为扩展方法可能会失去一些含义,因为无论格式是否真正有效,它都会出现在任何字符串上。只是一个小问题。

答案 2 :(得分:2)

是的,有可能:

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

为一个和两个参数的情况添加重载会很好。

总的来说,我没有看到太多的价值。

答案 3 :(得分:1)

是。

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

顺便说一句,此方法必须属于publicstatic类。

答案 4 :(得分:1)

确定......

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

答案 5 :(得分:1)

您应始终将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");

答案 6 :(得分:0)

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

是的,你可以。但它将解决的目的是什么?

答案 7 :(得分:0)

是的,有可能:

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"));

答案 8 :(得分:0)

是的,正如上面的每个人都说的那样。 但新的首选方式应该是:

$"string goes here {firstName} {lastName}";