簡體   English   中英

我可以為IEnumerable使用不同的Extension方法嗎? <T> 而不是 <T> ?

[英]Can I have a different Extension method for IEnumerable<T> than for <T>?

我有一個適用於任何類的擴展方法,但如果我正在處理IEnumerable<T> ,我想調用一個特殊版本。

例如

public static class ExtensionMethods
{

    public static dynamic Test<T>(this T source)
    {   
        dynamic expandoObject = new System.Dynamic.ExpandoObject();
        var dictionary = (IDictionary<string,object>)expandoObject;

        dictionary["Test"] = source.ToString();

        return dictionary;
    }

    public static IEnumerable<dynamic> Test<T>(this List<T> source)
    {
        var result = new List<dynamic>();
        foreach(var r in source)
            yield return r.Test();          
    }


    public static IEnumerable<dynamic> Test<T>(this IEnumerable<T> source)
    {
        var result = new List<dynamic>();
        foreach(var r in source)
            yield return r.Test();          
    }
}   

//用法

public class X 
{
    string guid = Guid.NewGuid().ToString();
}


void Main()
{
    List<X> list = new List<X>() { new X() };

    list.Test().Dump();                     // Correct but only works because there is an explicit overload for List<T>

    var array = list.ToArray();
    ((IEnumerable<X>) array).Test().Dump(); // Correct

     array.Test().Dump(); // Calls the wrong extension method
}

有沒有辦法讓array.Test()調用IEnumerable版本而不必顯式轉換它?

或者,如果我給擴展方法賦予不同的名稱,如果有任何方法,如果我意外地使用了錯誤的名稱,我會得到編譯器錯誤?

我想你正試圖以錯誤的方向解決它。 List實現IEnumerable接口,因此編譯器可能有問題解決將在List上調用的最佳方法。 你可以做什么 - 你可以測試IEnumerable是否是擴展方法中的列表。

public static IEnumerable<dynamic> Test<T>(this IEnumerable<T> source)
{
    if (source is List<T>) {
        // here 
    }
    var result = new List<dynamic>();
    foreach(var r in source)
        yield return r.Test();          
}

您可以指定T而不依賴於類型推斷,這將提示編譯器使用正確的擴展方法。 代碼看起來像這樣:

var array = list.ToArray();
array.Test<X>().Dump();

會發生什么,編譯器無法分辨使用哪個擴展,因為Array是兩個方法簽名的有效參數:

public static dynamic Test<T>(this T source) { .. }

public static IEnumerable<dynamic> Test<T>(this IEnumerable<T> source) { .. }

在第一種情況下,編譯器可以假設TArray類型。 因此,編譯器必須選擇一個(可能首先定義?)。

添加此擴展方法以顯式捕獲所有數組類型:

public static IEnumerable<dynamic> Test<T>(this T[] source)
{
    var result = new List<dynamic>();
    foreach(var r in source)
        yield return r.Test();          
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM