[英]C# String.Format optional parameters
我想使用帶有optional parameters
string.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());
}
並調用:
"{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,但像這樣更容易。
這種擴展方法不限於固定數量的參數。 也就是說,它可以處理像"{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
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#
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.