在string.format中格式化占位符以选择参数的子字符串

时间:2014-04-03 07:01:36

标签: c# string-formatting

是否有C#string.Format方法的格式字符串从相应的参数中选择子字符串?像这样:

var lang1 = "EN";
var lang2 = "FR";

var shortFormat = "Foo-{0:0-0}.pdf";
var longFormat = "Foo-{0:0-1}.pdf";

string.Format(shortFormat, lang1) // Foo-E.pdf
string.Format(shortFormat, lang2) // Foo-F.pdf
string.Format(longFormat, lang1) // Foo-EN.pdf
string.Format(longFormat, lang2) // Foo-FR.pdf

预计一些评论:是的,我知道Substring方法。我还读过string.Format比简单的Substring慢。上面的例子大大简化了。想象一下,string.Format语句驻留在一个地方,而lang1 / lang2参数是来自另一个地方的输入,而shortFormat / longFormat是在resx中定义的文件。

也就是说,在要定义格式的地方,我们对格式化的值(示例中的lang1 / lang2)一无所知,也没有任何方法可以执行C#代码。因此,我们不能在值上调用任何方法,例如Substring。反过来,在格式化代码运行的地方,我们将格式作为参数,因此我们不能简单地对值执行Substring因为我们不知道格式是否需要它(除非我们检查格式)。

3 个答案:

答案 0 :(得分:0)

不,string.Format没有此功能,在此处有更好的解释:Can maximum number of characters be defined in C# format strings like in C printf?

如果您不想使用Substring,我会为string创建一个扩展类,如下所示:http://msdn.microsoft.com/en-us/library/bb311042.aspx

namespace CustomExtensions
{
    public static class StringExtension
    {
        public static string ShortFormat(this string str)
        {
            // manipulate and return str here
        }
        public static string LongFormat(this string str)
        {
            // manipulate and return str here
        }
    }
}

答案 1 :(得分:0)

XSLT formatting可以是一个选项:用户可以在配置文件中提供几乎所有内容,甚至可以在您的域中执行自定义c#代码(如果需要)。

另请注意,格式的更改可以限制为相对较少的操作:裁剪,填充或在某些位置插入一两件事。每个都可以设置为单独的功能,并提供自己的参数。

答案 2 :(得分:0)

有两种方法可以提供自定义格式。您可以在自定义类型上实现IFormattable,以控制该类型的始终格式,或者在特定情况下,实现IFormatProvider,以覆盖其他类型的格式。

在您的情况下,我建议创建一种新类型以封装您的软件如何处理语言代码;

public struct LanguageCode : IFormattable {
   public readonly string Code;
   public LanguageCode(string code) {
      Code = code;
   }

   public override string ToString()
      => this.ToString("L", CultureInfo.CurrentCulture);
   public string ToString(string format)
      => this.ToString(format, CultureInfo.CurrentCulture);

   public string ToString(string format, IFormatProvider provider){
      if (String.IsNullOrEmpty(format))
         format = "L";
      if (provider == null)
         provider = CultureInfo.CurrentCulture;
      switch (format.ToUpperInvariant()){
         case "L": // Long
            return Code.ToString(provider);
         case "S": // Short
            return Code.SubString(0,1).ToString(provider);
         default:
            throw new FormatException($"The {format} format string is not supported.");
      }
   }

   public static implicit operator LanguageCode(string code)
      => new LanguageCode(code);
   public static implicit operator string(LanguageCode language)
      => language.Code;
}

然后从您的示例中获取

   var lang1 = (LanguageCode)"EN";
   LanguageCode lang2 = "FR";

   var shortFormat = "Foo-{0:S}.pdf";
   var longFormat = "Foo-{0:L}.pdf";