2012-06-21 39 views
5

即,我的方法如下述:在C#中,是否可以使用「我有的參數」來調用方法(具有默認參數)?

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]); 

是否有可能以更簡潔的方式做到這一點?

+1

見這個類似的問題:http://stackoverflow.com/questions/1996426/pass-multiple-optional-parameters-to-ac-sharp-function – Wug

+0

的參數總是以相同的順序? – blitzen

+0

@Wug,我不認爲這個問題有足夠的相似性,對OP有幫助。(除非OP想要使他的方法不易讀) –

回答

5

這裏有一個選擇,與你要重新聲明缺省值常數缺點:通過聲明的字符串作爲const小號

CreateTaskGroup(
    args[0], 
    args.ElementAtOrDefault(1) ?? "en-us", 
    args.ElementAtOrDefault(2) ?? "MyProject", 
    args.ElementAtOrDefault(3) ?? "DefaultTeam", 
    args.ElementAtOrDefault(4) ?? "abc"); 

您可以減少這個問題,如:

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()); 

這可能是一個有點難以閱讀,並不會太快,但它確實你問什麼,而不是訴諸重複的代碼或者對參數的默認值有任何不確定性。您可能想要爲太少或太多的參數添加一些錯誤處理。我喜歡這個解決方案。

2

如何在CreateTaskGroup像這樣

public static int CreateTaskGroup(params string[] args) 
{ 
    for (int i = 0 ; i < args.Length ; i++) 
    { 
     ............ 
0

這可能是最好的了,使用PARAMS是我想出來的:

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); 
+1

'參數[4]'不會爲空,它會拋出異常 – climbage

+0

我意識到在我發佈之後。 switch語句修復了它,但同時又使它變得醜陋。 :( – Wug

+0

但是現在所有變量的範圍只限於switch語句,不能在函數的其餘部分使用它們 – user1096188

2

這就是我將如何實現該類來保持事物清潔並將知道默認值的責任分配給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(); 
+0

That's so Java ... – user1096188

+0

哈!這很有趣。從來沒有用Java編程......模式必須已經轉移到.NET社區。 –

0

我會做這種方式..

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關鍵字是不是強制性的,但可能是方便......

相關問題