Reputation: 67544
Consider the following code:
using System;
using System.Linq;
using System.Collections.Generic;
public static class Ex
{
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, long cnt)
{
return source;
}
}
public class C
{
public static void Main()
{
foreach(var e in Enumerable.Range(0, 10).Take(5).ToArray())
Console.Write(e + " ");
}
}
I have an extension on IEnumerable<T>
for Take(long)
, which isn't provided by the framework. The framework only provides Take(int)
. And since I'm calling it with an int
parameter (Take(5)
), I would have expected it to use the framework version, but it's calling my extension.
Am I missing something? The closest match would obviously be the one that takes int
as a parameter, and System.Linq
is included so it should be in the pool of valid overloads. In fact if I delete my extension, the correct framework function is called.
Edit: Moving them to different namespaces shows the same problem:
using System;
using System.Linq;
using System.Collections.Generic;
namespace N1
{
public static class Ex
{
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, long cnt)
{
return source;
}
}
}
namespace N2
{
using N1;
public class C
{
public static void Main()
{
foreach(var e in Enumerable.Range(0, 10).Take(5).ToArray())
Console.Write(e + " ");
}
}
}
Upvotes: 0
Views: 89
Reputation: 95
Try System.Linq.Enumerable.Take(source, 5)
instead of just Take(source, 5)
to force using the original "Take" function or rename your own "Take" into somthing else "Takef" for example to avoid this kind of problems.
Upvotes: 0
Reputation: 89424
Because as Eric Lippert puts it:
the fundamental rule by which one potential overload is judged to be better than another for a given call site: closer is always better than farther away.
Upvotes: 2