在String.Format中包含If Else语句

时间:2010-08-18 04:17:48

标签: c# string string-formatting

我有以下声明。

  timespan = timespan.FromSeconds(236541)
  formattedTimeSpan = String.Format("{0} hr {1} mm {2} sec", Math.Truncate(timespan.TotalHours), timespan.Minutes, timespan.Seconds)

如果超过一小时,我必须将其格式化为“hrs mn sec”。我想在上面的String.Format中检查这个。

感谢。

7 个答案:

答案 0 :(得分:9)

最简洁的方法可能是编写自己的ICustomFormatter。这是一个方便的多元化格式的例子:

using System;

public class PluralFormatter : IFormatProvider, ICustomFormatter {

   public object GetFormat(Type formatType) {
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }

   public string Format(string format, object arg, 
                          IFormatProvider formatProvider)
   {   
      if (! formatProvider.Equals(this)) return null;

      if (! format.StartsWith("^")) return null;

      String[] parts = format.Split(new char[] {'^'});
      int choice = ((int) arg) == 1 ? 1 : 2;
      return String.Format("{0} {1}", arg, parts[choice]);
   }

   public static void Main() {
      Console.WriteLine(String.Format(
         new PluralFormatter(),
         "{0:^puppy^puppies}, {1:^child^children}, and {2:^kitten^kittens}", 
         13, 1, 42
      ));
   }
}

输出是,正如人们可能已经猜到的那样(and as seen on ideone.com):

13 puppies, 1 child, and 42 kittens

MSDN链接

答案 1 :(得分:7)

一种可能性是制作格式字符串的复数部分,并写:

formattedTimeSpan = String.Format("{0} hr{1} {2} mm {3} sec",
    Math.Truncate(timespan.TotalHours),
    Math.Truncate(timespan.TotalHours) == 1 ? "" : "s",
    timespan.Minutes,
    timespan.Seconds);

如果输出除了“1小时”以外的任何内容,这将在输出中插入“s”。

请注意,这对本地化不友好:其他语言与复数形式不同于英语。

答案 2 :(得分:3)

这里没有魔力。当您可以使用C#进行编码时,为什么要在format可能提供的任何条件下进行编码?

为避免重复代码,您可以将某些表达式提升为变量,并对它们使用条件:

timespan = timespan.FromSeconds(236541);
int hours = Math.Truncate(timespan.TotalHours);
string hoursUnit = hours == 1 ? "hr" : "hrs";
formattedTimeSpan = String.Format("{0}{1} {2} mm {3} sec",
                        hours, hoursUnit, timespan.Minutes, timespan.Seconds);

答案 3 :(得分:3)

我使用了一些扩展方法来帮助我处理这类事情:

public static string Inflect(this string noun, int count)
{
 return (count == 1 || noun.EndsWith("s", StringComparison.InvariantCultureIgnoreCase)) ? noun : noun + "s";
}

public static string Of(this int count, string noun)
{
 return string.Format("{0} {1}", count, noun.Inflect(count));
}

e.g:

"Hour".Inflect(1):小时

"Hour".Inflect(2):小时

0.Of("hour"):“0小时”

1.Of("hour"):“1小时”

5.Of("hour"):“5小时”

答案 4 :(得分:2)

您应该使用各种时间格式说明符。它有助于简化对Format()的调用。

var timespan = TimeSpan.FromSeconds(236541);
var formattedTimeSpan = String.Format("{0:hh} hr{1} {0:mm} mm {0:ss} sec",
    timespan, timespan.Hours != 1 ? "s" : "");

答案 5 :(得分:0)

没有“简单”的方法。

你可以这样做

string templateSingleHour = "{0} hr {1} mm {2} sec";
string templateMultiHour = "{0} hrs {1} mm {2} sec";
string template = Math.Truncate(timespan.TotalHours) > 1 ? templateMultiHour :templateSingleHour;
formattedTimeSpan = String.Format(template ...)

或者像这样

formattedTimeSpan = String.Format("{0} {3} {1} mm {2} sec", Math.Truncate(timespan.TotalHours), timespan.Minutes, timespan.Seconds, Math.Truncate(timespan.TotalHours) > 1 ? "hrs" : "hr");

答案 6 :(得分:0)

FWIW,如果您的应用程序将被用于我的非英语使用者,那么这不是一件轻而易举的事情。有一篇博文在http://www.siao2.com/2007/07/24/4022881.aspx

上阐述了这个问题