C#字符串。格式化可选参数
我想将C#字符串。格式化可选参数,c#,parameters,optional,string.format,C#,Parameters,Optional,String.format,我想将字符串.Format与可选参数一起使用: 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}是可选的,并具有默认值 你能帮我做这个吗?这取决于你所说的“可
字符串.Format
与可选参数一起使用
:
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}
是可选的,并具有默认值
你能帮我做这个吗?这取决于你所说的“可选参数”是什么意思 如果要用默认值自动替换
null
,最简单的方法是在参数中使用null合并运算符:
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以外的其他方法,例如,一个自定义方法,它将丢失的参数替换为其预期的默认值。您可以创建一个扩展方法:
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());
}
但是,它会强制您按顺序指定参数,因此如果要设置{4},则不能跳过{3}。但是,您可以添加:
for(var x = 0; x < args.Count; ++x){
if(args[x] == null) args[x] = String.Empty;
将{0}和{2}设置为String.Empty,但将{1}、{3}和{4}默认设置为String.Empty
您可以自动确定i,但这样容易多了。这种扩展方法不限于固定数量的参数。也就是说,它将处理字符串,如
“{0}”
,但也可以处理“{0}{1}”
,“{0}{1}{2}”
等等。
次要的缺点是,首先给出可选参数,然后给出非可选参数。应该是另一种方式,但不幸的是,params
关键字的性质禁止这样做。
主要的缺点是它忽略了大括号中的数字(尽管解决方案也可以修改以包含该数字)
private static Regex curlyBracketRegex=new Regex(“\\{(.+?)\\}”);
私有静态字符串OptionalFormat(字符串格式字符串,参数对象[]args)
{
var numberOfArguments=curlyBracketRegex.Matches(formatString.Count);
var missingArgumentCount=numberOfArguments-args.Length;
if(missingArgumentCount string.Empty)).ToArray();
返回string.Format(formatString,args);
}
上述方法适用于简单格式字符串。正则表达式检测花括号。如果matches计数高于传递的参数数,则将创建一个新数组,将原始数组与空字符串组合
示例:OptionalFormat(“{0}{1}”,“apple”)//apple#我认为您不能用
String.Format
,您到底想实现什么,可能是您可以使用String.Join
连接未知数量的字符串元素。这不是可选参数。您正在为占位符{1}
@CriketerOnSO传递至少一些值:这取决于OP想要做什么。我将详细说明我的答案。@criketeron因此,如果不传递一个值,就无法使用String.Format
来实现这一点。Thx Heinzi供您建议,但我有一个问题,我在资源文件中定义了“{0}{1}”,我不知道最终用户是否会给出所有参数,因此,如果最终用户没有给出所有参数,我将有一个例外,因此我想使用{1}作为可选参数parameter@KernelMed您不能-您必须至少具有与该格式中的索引值相同数量的参数。
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");
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
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);
}