Thorin Oakenshield
Thorin Oakenshield

Reputation: 14682

Why params does not accept generic types?

Here is my scenario,

A function :

    public String StringConcat(params String[] parameter)
    {
        String l_strReturnValue = String.Empty;
        for (Int32 l_nIndex = 0; l_nIndex < parameter.Length; l_nIndex++)
        {
            l_strReturnValue += parameter[l_nIndex];
        }
        return l_strReturnValue;
    }

And i'm calling it like

        List<String> l_lstTest = new List<string> { "A", "B", "C" };
        String l_strString = StringConcat(l_lstTest.Select(X => X).ToArray());

it returns the value as "ABC"

But its showing error if I call the function without type convrsion like

        String l_strString = StringConcat(l_lstTest.Select(X => X));

So how to use the function without conversion ?

Note 1 :

In XDocument Add method - they have used like params, but there is no such needs of type conversions.

Note 2 :

The purpose of this post is not to add the strings, just want to learn more about the limits of params.

Upvotes: 0

Views: 161

Answers (3)

onof
onof

Reputation: 17367

It's a limitation of params by design, because if you were using

  public String StringConcat(params object[] parameter)

and you called with IEnumerable, you couldn't figure out if the parameter is a single parameter or it should iterate on the enumerable. For instance, without this limitation, in

  StringConcat( l_lstTest.Select(X => X) )

the IEnumerable should be an element of the list of parameters or it's the list of parameters?

Upvotes: 1

Jon
Jon

Reputation: 437376

The limits of the params keyword is that the parameter must be an array type.

l_lstTest.Select(X => X) is an IEnumerable<string>, not an array, so it does not match the formal parameter type. It doesn't work for the same reason it would not work if you tried to pass a plain int.

To make it work, you should add another overload of the method:

public String StringConcat(IEnumerable<string> parameter)
{
    // your code here
}

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1500575

The return type of Select(X => X) will be IEnumerable<string> - not an array. So you need another overload:

public String StringConcat(IEnumerable<string> parameter)

You'd probably make the array overload call this overload.

(And yes, obviously you'd want to use StringBuilder instead of repeated string concatenation - and foreach instead of a for loop.)

Note that the relevant XDocument.Add overload takes a params Object[] parameter, not params String[] - and LINQ to XML works such that if you try to add something which is itself enumerable, it's as if you added each item in turn. That's not part of the language - it's part of the implementation. So if you call:

doc.Add(someStringArray.Select(x => x))

that will actually just call XDocument.Add(object) which will notice that the argument implements IEnumerable.

Upvotes: 4

Related Questions