繁体   English   中英

对 C# 的扩展方法重载解析感到困惑

[英]Confused about C#'s extension method overload resolution

考虑以下代码:

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 + " ");
    }
}

我在IEnumerable<T>上有一个Take(long)的扩展,框架没有提供。 该框架仅提供Take(int) 而且由于我使用int参数( Take(5) )调用它,我本来希望它使用框架版本,但它正在调用我的扩展。

我错过了什么吗? 最接近的匹配显然是将int作为参数的匹配,并且System.Linq包含在内,因此它应该在有效重载池中。 事实上,如果我删除我的扩展,就会调用正确的框架 function。

以供参考

编辑:将它们移动到不同的名称空间显示相同的问题:

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 + " ");
        }
    }
}

以供参考

因为正如 Eric Lippert 所说:

对于给定的呼叫站点,判断一个潜在过载比另一个更好的基本规则:越近总是比越远越好。

越近越好

尝试System.Linq.Enumerable.Take(source, 5)而不是Take(source, 5)强制使用原始的“Take” function 或将您自己的“Take”重命名为其他“Takef”,例如以避免这种情况的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM