簡體   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