[英]In C#, is it possible to call a method (which has default parameters) with “as many parameters as I have”?
也就是說,我有一個如下方法:
public static int CreateTaskGroup(string TaskGroupName,
string Market = "en-us", string Project = "MyProject",
string Team = "DefaultTeam", string SatelliteID="abc");
我想通過讀取標准的命令行參數數組從命令行調用此方法。 顯而易見的方法如下:
if (args.Length == 1) CreateTaskGroup(args[0]);
if (args.Length == 2) CreateTaskGroup(args[0], args[1]);
if (args.Length == 3) CreateTaskGroup(args[0], args[1], args[2]);
是否有可能以更簡潔的方式做到這一點?
這是一個替代方案,您必須重新聲明默認值常量:
CreateTaskGroup(
args[0],
args.ElementAtOrDefault(1) ?? "en-us",
args.ElementAtOrDefault(2) ?? "MyProject",
args.ElementAtOrDefault(3) ?? "DefaultTeam",
args.ElementAtOrDefault(4) ?? "abc");
您可以通過將字符串聲明為const
來減少此問題,例如:
public const string MarketDefault = "en-us";
public static int CreateTaskGroup(string TaskGroupName,
string Market = MarketDefault, ...)
static void Main(string[] args)
{
CreateTaskGroup(
args[0],
args.ElementAtOrDefault(1) ?? MarketDefault,
...);
}
但是,編譯器並不能保證, MarketDefault
實際上仍然是(代碼可以在未來重構) Market
的默認值。
編輯:這是一個替代解決方案,使用反射:
var argsForMethod = new List<string>(args);
var m = typeof(Program).GetMethod("CreateTaskGroup");
foreach (var p in m.GetParameters().Skip(args.Length))
if (p.Attributes.HasFlag(ParameterAttributes.HasDefault))
argsForMethod.Add((string)p.DefaultValue);
else
throw new NotImplementedException();
var result = (int)m.Invoke(null, argsForMethod.ToArray());
這可能有點難以閱讀,並且不會太快,但它會按照您的要求進行操作,而無需使用重復代碼,或者對參數的默認值有任何不確定性。 您可能希望為太少或太多的參數添加一些錯誤處理。 我更喜歡這個解決方案
如何在CreateTaskGroup中使用params這樣的東西
public static int CreateTaskGroup(params string[] args)
{
for ( int i = 0 ; i < args.Length ; i++ )
{
............
這就是我實現類以保持清潔並將責任分配給TaskGroupCreator的責任。
public class TaskGroupCreator
{
private string[] values;
public TaskGroupCreator(string[] values)
{
this.values = values;
}
public string TaskGroupName
{
get { return values[0]; }
}
public string Market
{
get { return this.GetElement(1, "en-us"); }
}
public string Project
{
get { return this.GetElement(2, "MyProject"); }
}
public string Team
{
get { return this.GetElement(3, "DefaultTeam"); }
}
public string SatelliteID
{
get { return this.GetElement(4, "abc"); }
}
public int CreateTaskGroup()
{
// Do stuff with your properties...
}
private string GetElement(int index, string defaultValue)
{
return this.values.ElementAtOrDefault(index) ?? defaultValue;
}
}
用法:
var taskGroup = new TaskGroupCreator(args).CreateTaskGroup();
這可能是我提出的最好的結果:
public static int CreateTaskGroup(string[] arguments)
{
// optional error handling here
string TaskGroupName = arguments[0];
string Market = arguments.ElementAtOrDefault(1) ?? "en-us";
string Project = arguments.ElementAtOrDefault(2) ?? "MyProject";
string Team = arguments.ElementAtOrDefault(3) ?? "DefaultTeam";
string SatelliteID = arguments.ElementAtOrDefault(4) ?? "abc";
// function body as it was
這樣做的同樣但不簡潔:
public static int CreateTaskGroup(string[] arguments)
{
string TaskGroupName, Market, Project, Team, SatelliteID;
switch (arguments.Length)
{
case 5:
string SatelliteID = arguments[4] ?? "abc";
goto case 4;
case 4:
string Team = arguments[3] ?? "DefaultTeam";
goto case 3;
case 3:
string Project = arguments[2] ?? "MyProject";
goto case 2;
case 2:
string Market = arguments[1] ?? "en-us";
goto case 1;
case 1:
string TaskGroupName = arguments[0];
break;
case 0:
// error handling here;
}
// function body as it was
你可以簡潔地稱它為:
CreateTaskGroup(args);
我這樣做..
CreateTaskGroup(args);
//.....
public static int CreateTaskGroup(params string[] args) {
if (args.Length == 0) throw new Exception("nope!");
args = args.Concat(Enumerable.Range(0, 5 - args.Length)
.Select<int, string>(_ => null)).ToArray();
string TaskGroupName = args[0];
string Market = args[1] ?? "en-us";
string Project = args[2] ?? "MyProject";
string Team = args[3] ?? "DefaultTeam";
string SatelliteID = args[4] ?? "abc";
//......
}
params
關鍵字不是強制性的,但可以方便...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.