5

也就是说,我有一个方法如下:

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

是否有可能以更简洁的方式做到这一点?

4

5 回答 5

4

这是一种替代方法,缺点是您必须重新声明默认值常量:

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

您可以通过将字符串声明为 s 来减少此问题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());

这可能有点难以阅读,并且不会太快,但是它可以满足您的要求,而无需使用重复的代码,也不会对参数的默认值有任何不确定性。您可能希望为太少或太多的参数添加一些错误处理。我更喜欢这个解决方案。

于 2012-06-21T23:40:05.783 回答
2

在 CreateTaskGroup 中使用类似这样的参数怎么样

 public static int CreateTaskGroup(params string[] args) 
 {
    for ( int i = 0 ; i < args.Length ; i++ )
    {
      ............
于 2012-06-21T23:40:48.047 回答
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();
于 2012-06-21T23:50:34.583 回答
0

这可能是我想出的最好的:

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);
于 2012-06-21T23:42:20.073 回答
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关键字不是强制性的,但可能很方便......

于 2012-06-21T23:55:19.737 回答