Reputation: 91734
Let's take the following extension method:
static class Extensions
{
public static bool In<T>(this T t, params T[] values)
{
return false;
}
}
I'm curious as to why this code compiles and runs:
var x = new Object();
IEnumerable<int> p = new List<int> { 1, 2, 3 };
var t2 = x.In(p);
Within In
, values
is an Object[]
, as if the List<int>
gets converted on the fly to an array. To me, it seems that params T[]
does not match IEnumerable<int>
, which is why I'm surprised this even runs.
Now this code:
var x = 5;
IEnumerable<int> p = new List<int> { 1, 2, 3 };
var t2 = x.In(p);
Does not run and generates the compiler error:
Error 2 Argument 2: cannot convert from 'System.Collections.Generic.IEnumerable' to 'int[]'
This is what I'd expect from the first one actually. Can someone explain what's going on here? Thanks!
Upvotes: 28
Views: 1206
Reputation: 888293
Type inference converts your first call to
In<object>(x, p);
The parameters of this closed generic method are object, params object[]
.
Therefore, passing p
implicitly converts it to an object
, which becomes the single item in the params array.
Your second call is inferred (because of the first parameter) to
In<int>(x, p);
Here, the second parameter can either be an int[]
(passing an array directly) or a series of int
s (via params
).
Since IEnumerable<int>
is neither of those, you get an error.
Upvotes: 40