Wasn't the goal, and hope for .Net 2 / the next version of C# not to rely on boxing of objects For it is the cornerstone of Generics...typesafe arrays and no more boxing!
But one area was overlooked.....take for example this code using the params keyword
public void Columns(params string[] ColumnNames) { ... }
Nice convention! It saves keystrokes and makes code easier to use...but it was not updated to use generics! The following code in .Net 2 gets the dreaded CS0225 error erronously telling the user that a single dimensional array is not being used....
public void Columns(params List<string> items ) { ... }
Feel free to tell me that List<string> is not a single dimensional array. I sure think it is. Obviously the error text should say "params parameter must be a single dimensional array and must not be a generic list" but that is not the direction of the post.
The question is this, "Why wasn't the params lexical analysis for version two changed to handle generics "
All thoughts appreciated and welcome. How about in the next version

params parameter must be a single dimensional array - (It is! Tell me it isn't!)<g>
kadabba
I think this hits the root of why you think List<> is like an array:
An array is a single pointer to a block of references or values. A list is an ordered collection of pointers to references or values. This is why there is no easy way to insert a new value into the middle of an array. Fundimentally, an array is no more similar to a List<> than it is to a hashtable or stack.
And as an aside, don't forget you can call List<>'s ToArray() method
List<int> aList = new List<int>();
...
Method( aList.ToArray() );
elainel311
What would having the params collected into a List<string> versus a string[] buy you An example would make your suggestion more compelling.
-Tom Meschter
Software Dev, Visual C# IDE
Ultrawhack
I agree with the your point of supporting variable arguments, but I also have to respectfully disagree...It also saves the user having to do these steps: create and allocate an array, then add the items, and then pass it in....if that is not saving keystrokes....<g> but this is not my intention of the original post.
I agree with you that arrays need to be supported. But, my point in a nutshell is that programming languages have to be symmetrical in design and implementation. The grammar of a language that orchestrates the lexical analyses is built on such symmetry. (IMHO) I believe that this post points out the failure of such symmetry currently not found in C#; let me explain why
The definition of params as found in the C# language:
paramsmodifier. There can be only one parameter array for a given method, and it must always be the last parameter specified. The type of a parameter array is always a single dimensional array type.If one looks at the grammar of C# concerning the params this is what one sees
parameter-array:
attributesopt params array-type identifier
Array-type and its identifier…. The disconnect must be that array-type does not allow for a generic List<>. I consider List<> to be an array type.
If one specifies that the array-type on the target method declaration as List<T> vs. T[ ], shouldn’t that work Remember .Net 2 has already expanded the params grammar to handle generic functions such as
void PushMultiple<T>(Stack<T> stack, params T[ ] values)
EtherealSky
Why do you insist that a List<string> is an array While it has some SIMILARITIES to arrays, its not at all the same thing as an array. And just being similar isn't sufficient. I can't create a class thats SIMILAR to an existing one, and use it in place of that class. The compiler wont allow it. Now, if I declare my new class to derive from the other class, then it is allowed. But, List<stirng> is not derived from string[] or Array, nor should it be. Yes, I agree that they COULD have decided to allow the syntax you describe. But doing so would require more than just lexical analysis changes. And beyond that, where would it stop Should we allow them to use non-generic List, or LinkedList, or any number of other list-like variations No, they stuck with Array, because its simple and does the job.
And, using strongly-typed arrays does NOT cause boxing, btw.
RMooreFL
I consider the strength of C# to be the fact that it is a generational language, meaning that it is continuing to evolve. I look at C/C++ and to a lesser extent Java and don't feel they are (or were) as dynamic as the growth of C#.
When .Net 1 came out with C#, the modus operandi was the array and array list. An infrastructure was built around those items to support them, and one was the params keyword. With .NET 2 one of the new paradigms was generics lists, which in my mind are far superior, in most respects, to the arrays, arraylist and hashtable (I will refer to them as array paradigm here on out). I hardly use the array and exclusive use the generic counterparts.
To me what is missing is the ability to use a generic list with params keyword. It feels like the infrastructure to facilitate the usage of the new paradigm was not completed for generic lists. In my mind, to be consistent, if a user wants have parameter data consumed from a generic list, instead of an array when using the params...why not The infrastructure should accommodate both and we are on a new paradigm of handling data.
List<x> has a toArray(), but there is not counterpart in the array world to output a generic list. Its Gen2 accommodating for Gen 1. It just feels the infrastructure should also accommodate for Gen 2 in the same manner.
...IMHO
Mike36
Argus.Antony
Here is the official response from Microsoft. Thanks to all that have participated in this thread and gave opinions.
MukilanP
Hooper
Christopher Lusardi
static void Method(params String[] parameters)
{
}
static void Form1Test()
{
Method("one", "two", "three");
Method(new String[] { "one", "two", "three" });
What symmetry There may be a certain consistency in a language's grammar; but symmetry is something else. I don't see what sort of "symmetry" you're alluding to between the definition of params and the BNR notation of params. They both say the type is Array, seems consistent to me.
List<> is not an array type, if it were you could use it as a params type.
params isn't just a C# thing, there's also the ParamArrayAttribute that can be used in VB, or any other language that doesn't have syntax for params compatibility. Changing the way params works would need symmetry amounts all other .NET languages, good luck with that.
params essentially uses a built-in type, or a type that's specified to be in all CLI implementations (because Array is in the BCL which is specified to be supported by the Kernel profile--the base implementation requirement for a CLI implementations). Generics are also in the BCL; but, the parametrized type may not. For example, I can define a type MyClass to be used as the argument for List<>. Since MyClass isn't in the BCL there's no way for external applications to call a method defined as Method(params List<MyClass>) because it can't be sure that's legal in any baseline CLI implementation.
By the way, the type of the parameter is Array; but the argument need only derive, or implement, Array (hence String[], MyClass[], etc. all work, which is done by the compiler--you can directly derive from Array). You get type safety with params. There's nothing to be gained by supporting List<T> or any other generic.
Array may be been a poor choice, an IList interface may have been better, but that's moot now.
jepptje
This hits exactly on the issue. I fully believe that List<T> as introduced in version two of C# is just as much of an array as the array introduced in version one, T[ ]. I will explain why after responding to a section in Peter's post relating to the low-level params umbrella.
Its to my understanding that if one creates an array of unsigned data types, that those are not cross-language compatible, yet one can create and pass them via the params construct. I simply cannot believe that it is the payload that is nixing the fact that List<t> cannot be used. An array is the highway, the data are cars. The generic list/collection is a highway just as an array. It can carry safe items or explosive items....and as stated by you, both are in the BCL.
Mark Marquis
I agree that what you suggest could probably be accomplished. But, you keep muddling the issue by calling a List<int> and array. Its not. List<int> is what it is and an array is an array. They are similar and that similarity is captured in the fact that both are examples of IList. So, one could argue that the params construct should be supported for any type that implements IList and has a parameterless constructor, or something along that lines. But calling List<int> an Array is an incorrect use of the vocabulary. An Array means a very specific kind of object in .NET, and arbitrarily applying it to other objects will only create confusion and impede one's ability to talk about .NET code in a concise manner.
TRID
static void Method(params int[] parameters)
{
// ...
}
// ...
Method(new int[] { 1});
The call to Method gets compiled to the following IL:[code language="IL"] .locals init (
[0] int32[] CS$0$0000)
L_0000: nop
L_0001: ldc.i4.1
L_0002: newarr int32
L_0007: stloc.0
L_0008: ldloc.0
L_0009: ldc.i4.0
L_000a: ldc.i4.1
L_000b: stelem.i4
L_000c: ldloc.0
L_000d: call void WindowsApplication4.Program::Method(int32[])[/code]You'll notice there are no boxing instructions.
Arrays for params would always have to be supported for the case of calling a .NET 1.1 assembly; why introduce another method of doing something where it is not needed