Why Use the Params Keyword

Why use the params keyword?

With params you can call your method like this:

addTwoEach(1, 2, 3, 4, 5);

Without params, you can’t.

Additionally, you can call the method with an array as a parameter in both cases:

addTwoEach(new int[] { 1, 2, 3, 4, 5 });

That is, params allows you to use a shortcut when calling the method.

Unrelated, you can drastically shorten your method:

public static int addTwoEach(params int[] args)
{
return args.Sum() + 2 * args.Length;
}

Why use the params keyword

Which of these calls to Console.WriteLine do you find clearer?

Console.WriteLine("Hello {0}, you are {1}", person.Name, person.Age);

or

Console.WriteLine("Hello {0}, you are {1}",
new object[] { person.Name, person.Age });

(You can't even use implicitly typed arrays (new[]) in the above case, unless either person.Name or person.Age is of type object... If they were both of type string you'd be okay, but it would create a string array...)

I prefer the first. It's simpler to read. That's all there is to params - it just allows the callers to use more concise syntax. You can still pass an array reference in the normal way, as you do in your code - but you could also just write:

Prints("cs150", "cs250", "cs270", "cs300", "cs350");

... which again, is simpler to read than declaring a separate variable.

C#: params keyword vs. list

The params keyword is syntactic sugar handled by the C# compiler. underneath the hood, it's actually turning

void Foo(params object[] a) { ... }
Foo(1,2,"THREE");

into

void Foo(object[] a) { ... }
Foo(new object[] { 1, 2, "THREE" })

From a performance perspective like you're asking about, the params call is simply faster because it is a bit faster to create an array than it is to create a List<>. There is no performance difference between the two snippets above.

What does params keyword in method signature really mean

Have you ever used Console.WriteLine?

Console.WriteLine("{0}: The value of {1} is {2}.", lineNumber, foo, bar);

This sort of call is where params can be useful. Having to explicitly construct an array to contain your parameters is just noise which makes the code harder to read without adding any value. Compare to the how it would look if params weren't used:

Console.WriteLine("{0}: The value of {1} is {2}.", new object[] { lineNumber, foo, bar });

The second version adds no useful information to the code, and moves the values further from the format string, making it harder to see what is going on.

Is params Keyword supports with ValueTuple as a parameter C# 7.0?

A parameter array is a very specific language feature that is only applicable to method parameters. A value tuple is a struct with variable length generic parameters and has been given a special syntax for initialization and usage (most of which are just smoke an mirrors).

var asd = ("asd","asd");

Is basically just syntactic sugar for

ValueTuple<string, string> valueTuple = new ValueTuple<string, string>("asd", "asd");

There isn't even anything overly magical about named tuples.

var asd = (bob1 : "asd", bob2 : "asd");
Console.WriteLine(asd.bob1);

Basically converts to the following

ValueTuple<string, string> valueTuple = new ValueTuple<string, string>("asd", "asd");
Console.WriteLine(valueTuple.Item1);

So you are essentially asking, why you can't use params in a tuple initializer syntax.

Well, as discussed, because a value tuple initializer actually isn't a method, and as much as it looks like it, the arguments you give it are not a method parameters. Tuple syntax is it's own very special language feature. However, you do have options.

So let's look at what you are trying to achieve. If you had a method parameter as such

public void Test((string arg1, params string[] args) tuple)

the only advantage would be you could supply a comma separated list.

Test(("bob","args1","args2","args3"));

Since we can't, your options are

Test(("bob",new []{"args1","args2","args3"}));

Or with some tomfoolery you could use an explicit operator on your own struct.

public readonly struct Testing
{
public Testing(ITuple x)
{
CategoryName = (string) x[0];
Properties = EnumerateTuple<string>(x).ToArray();
}
public Testing(string categoryName,string[] properties)
{
CategoryName = categoryName;
Properties = properties;
}

private static IEnumerable<T> EnumerateTuple<T>(ITuple x)
{
for (var i = 1; i < x.Length; i++)
yield return (T) x[i];
}
public string CategoryName { get; }
public string[] Properties { get; }
public static implicit operator Testing((string, string[]) x) => new Testing(x.Item1,x.Item2);
public static implicit operator Testing(string x) => new Testing(x, Array.Empty<string>());
public static implicit operator Testing((string, string) x) => new Testing(x);
public static implicit operator Testing((string, string,string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string, string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string, string, string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string, string, string, string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string, string, string, string, string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string, string, string, string, string, string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string, string, string, string, string, string, string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string, string, string, string, string, string, string, string) x) => new Testing(x);
public static implicit operator Testing((string, string, string, string, string, string, string, string, string, string, string, string) x) => new Testing(x);
}

Which would allow shenanigan's such as this

public static void Test(Testing something)
{
Console.WriteLine(something.Category);
Console.WriteLine(string.Join(", ", something.Properties);
}

private static void Main(string[] args)
{
Test("asd");
Test(("asd"));
Test(("asd", "args1"));
Test(("asd", "args1", "args2"));
Test(("asd", new []{"args1", "args2"}));
}

Note : This was only for academic purposes, I really wouldn't expect anyone to want to do this

What is a real example of when to use params as a method argument?

Math.Min takes exactly two arguments. This is a stupid limitation. Many other languages allow you to write:

double x, y, z, w;
double least = min(x, y, z, w);

If you wanted to write a min function that could be used like that, you'd want to use params.

Can you use the params keyword in a delegate?

You can't have custom attributes on a generic type argument (the CLI doesn't permit it), and the C# compiler implements the params keyword by emitting the System.ParamArrayAttribute on the relevant method parameter.

This stops you from using it with the System.Func<...> generic delegates, but you can always create your own delegate type that does use params.

Params vs. List T , When should I use params keyword and when to use List t

params as it will give you the ability to pass in an array. It doesn't seem like you would want to pass in a list because that would give you extra functionality on the parameter that doesn't make sense. Like Add for example.

Params keyword in JSON object

Use @params so you can escape special keywords



Related Topics



Leave a reply



Submit