C#String.Format可选参数

问题描述 投票:4回答:4

我想用string.Formatoptional parameters

public static void Main(string[] args)
{
    // Your code goes here
    // Console.WriteLine(string.Format("{0} {1}", "a", "b"));
    Console.WriteLine(string.Format("{0} {1}", "a"));
}

例如,参数{1}是可选的并且具有默认值

你能帮帮我吗?

c# parameters optional string.format
4个回答
4
投票

这取决于“可选参数”的含义。

如果要使用默认值自动替换null,最简单的方法是在参数中使用null coalescing运算符:

String.Format("{0} {1}", 
              "a",
              someNullableVariableContainingB ?? "default value");

如果要为多个String.Format调用重用相同的格式化字符串,例如

var myFormatString = "{0} {1}";
var string1 = String.Format(myFormatString, "a", "b");
var string2 = String.Format(myFormatString, "a");

那么你运气不好:如果提供的参数太少,String.Format将抛出异常,并且无法在格式字符串中指定“可选参数”。您将不得不使用除String.Format之外的其他内容,例如,使用其预期的默认值替换缺少的参数的自定义方法。


1
投票

该扩展方法不限于固定数量的参数。也就是说,它可以使用像"{0}"这样的字符串,还可以使用"{0} {1}""{0} {1} {2}"等字符串。最小的缺点是,首先你提供可选参数,然后是非可选参数。应该是反过来但不幸的是params关键字的性质禁止这样做。主要的缺点是它忽略了大括号中的数字(尽管解决方案可以重新设计以包含它)。

    public static string FormatOpt(this string s, string optional, params string[] param)
    {
        StringBuilder result = new StringBuilder();
        int index = 0;
        bool opened = false;
        Stack<string> stack = new Stack<string>(param.Reverse());

        foreach(var c in s)
        {
            if (c == '{')
            {
                opened = true;
                index = result.Length;
            }
            else if (opened && c == '}')
            {
                opened = false;
                var p = stack.Count > 0 ? stack.Pop() : optional;
                var lenToRem = result.Length - index;
                result.Remove(index, lenToRem);
                result.Append(p);
                continue;
            }
            else if (opened && !Char.IsDigit(c))
            {
                opened = false;
            }

            result.Append(c);
        }

        return result.ToString();
    }

并且有预期的结果:

string res1 = "result: {0}, {1}, {2}, {3}".FormatOpt("optional", "first param", "second param");
// result: first param, second param, optional, optional

string res2 = "result: {0}, {1}, {2}, {3}".FormatOpt("optional", "first param");                 
// result: first param, optional, optional, optional

string res3 = "result: {0}, {1}, {2}, {3}".FormatOpt("optional");                                
// result: optional, optional, optional, optional

1
投票
  private static Regex curlyBracketRegex = new Regex("\\{(.+?)\\}");

  private static string OptionalFormat(string formatString, params object[] args)
  {
        var numberOfArguments = curlyBracketRegex.Matches(formatString).Count;

        var missingArgumentCount = numberOfArguments - args.Length;
        if (missingArgumentCount <= 0) //more argument or just enough
            return string.Format(formatString, args);

        args = args.Concat(Enumerable.Range(0, missingArgumentCount).Select(_ => string.Empty)).ToArray();
        return string.Format(formatString, args);
  }

上面的方法适用于简单的格式字符串。正则表达式检测大括号。如果匹配计数高于传递的args的数量,则将创建一个新数组,将原始数组与空字符串组合在一起。

示例:OptionalFormat(“{0}#{1}”,“apple”)// apple#


0
投票

您可以创建一个扩展方法:

public static string MyFormat(this string s, int i, params string[] args){
    var t = new List<string>(args);
    for(var c = t.Count; c < i; ++c)
        t.Add(String.Empty); // or other default

    return String.Format(s, t.ToArray());
}

并致电:

"{0}:{1} - {2},{3},{4}".MyFormat(5, "ping", "fnord");

但是它会强制您按顺序指定参数,因此如果要设置{4},则不能跳过{3}。但是你可以添加:

for(var x = 0; x < args.Count; ++x){
    if(args[x] == null) args[x] = String.Empty;

并致电:

"{0}:{1} - {2},{3},{4}".MyFormat(5, "ping", null, "pong");

设置{0}和{2},但默认为{1},{3}和{4}为String.Empty;

你可以自动确定i,但这样就容易多了。

© www.soinside.com 2019 - 2024. All rights reserved.