In C #, is it possible to call a method (which has default parameters) with "as many parameters as I have"?

That is, I have a method like:

public static int CreateTaskGroup(string TaskGroupName, 
    string Market = "en-us", string Project = "MyProject", 
    string Team = "DefaultTeam", string SatelliteID="abc");

I would like to call this method from the command line, reading a standard array of command line arguments. The obvious way to do this would be as follows:

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

Can this be done in a more concise way?

+5
source share
5 answers

Here is one of the alternatives, with the drawback that you have to override the default constants:

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

You can reduce this problem by declaring strings as consts, for example:

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

, , , - . , . .

+5

CreateTaskGroup -

 public static int CreateTaskGroup(params string[] args) 
 {
    for ( int i = 0 ; i < args.Length ; i++ )
    {
      ............
+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();
+2

This is probably the best of what I came up with:

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

This does the same, but less concise:

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

You can call it briefly as follows:

CreateTaskGroup(args);
0
source

I would do it like this.

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 a keyword is optional, but may be convenient ...

0
source

All Articles