2011-03-28 100 views
4

我想重載一個泛型列表的Add方法,所以我可以用集合初始化,如:重載泛型列表的添加與擴展方法

var x = new List<Tuple<string>> { { "1", "2" }, { "1", "2" } }; 

(如果元組是一個二進制元組的一個簡單的自定義實現) 但是,我創建了一個擴展方法,在cs文件中放入一個using指令,並仍然得到「No overload for method'Add'需要2個參數」--error。
是否可以做(使用擴展方法)?

擴展方法代碼:

namespace ExtensionMethods { 
    public static class Extensions{ 
     public static void Add<T>(this List<Tuple<T>> self, T value1, T value2) { 
      self.Add(new Tuple<T> { value1, value2 }); 
     } 
    } 
} 
+0

我想這是不可能的,因爲你要如何使用它,以及如何對象初始化工作的差異。雖然有人可能會對此提出建議。此外我懷疑對象初始化器將與擴展方法一起使用。 – Snowbear 2011-03-28 10:46:57

+4

有趣的是,在[Visual Basic](http://msdn.microsoft.com/en-us/library/dd293683.aspx)中支持這種** ** – Blorgbeard 2011-03-28 11:24:46

+1

存在連接問題,如果您希望看到它也添加到C#中:https://connect.microsoft.com/VisualStudio/feedback/details/459307/extension-add-methods-are-not-considered-in-c-collection-initializers – jeroenh 2011-05-03 14:56:51

回答

1

在C#6.0 [0]微軟允許在集合初始化使用的擴展方法。歡呼:)

而且,因爲這不是一個.NET Framework或CLR變化,但是編譯器的變化,此功能可以在.NET 4.0中使用。

所以下面是現在有效的C#代碼。(在Visual Studio 2015年RC測試)

class Program 
{ 
    static void Main(string[] args) 
    { 
     var x = new List<Tuple<string,string>> { { "1", "2" }, { "1", "2" } }; 
    } 
} 
public static class Extensions 
{ 
    public static void Add<T1,T2>(this List<Tuple<T1,T2>> self, T1 value1, T2 value2) 
    { 
     self.Add(Tuple.Create(value1, value2)); 
    } 
} 

C# 6 Features [0]

1

無法實現使用擴展methods.Extension方法構造不過這需要在一個對象實例的靜態方法。因此,您需要首先有一個實例能夠傳遞給它。

但是,您可以使用List的AddRange()來初始化您的列表。

+4

它是不是關於構造函數,而是關於需要適用的'Add'方法的集合初始化方法。 – Snowbear 2011-03-28 10:50:48

+0

實際上,它是關於構造函數作爲元組實例必須首先創建的,然後才能將其添加到列表>。 – 2011-03-28 12:11:54

+1

@Panagiotis,不,這不是關於構造函數。元組構造器必須被調用,但它幾乎與對象初始化器無關。 – Snowbear 2011-03-28 12:26:55

2

這是不可能通過擴展方法。爲了使這個語法工作,你必須創建你自己的集合類,它將具有void Add(T value1, T value2)簽名。

P.S .:你所做的不是overload並且沒有辦法在現有類中重載任何東西。

UPDATE:看起來像我的第一句話應該是:「它通過在C#擴展方法是不可能

+0

嗯......我試圖添加一個方法到一個已經有一個名字相同,但是參數不同的方法。如果這不是超載,它是什麼? – 2011-03-28 11:32:54

+1

我告訴這個的原因是因爲擴展方法並沒有真正添加到Type中。你可以調用它們,使它看起來像是類型的一部分,但它們仍然不是它的一部分。 – Snowbear 2011-03-28 11:43:56

+1

[VB.NET獲取所有的愛。](http://msdn.microsoft.com/en-us/library/dd293683.aspx):/ – canon 2013-08-21 14:45:25

0

擴展方法不能重載他們的目標類型,只是因爲他們是定義的任何方法不是目標類型的成員。擴展方法不會向其目標類型添加任何內容。它們只是編譯器的魔力,它們可以被調用,就好像它們是在其目標類型上定義的方法一樣。實際上,它們是在單獨的靜態類型中定義的,因此它們不能在其目標類型上重載任何方法。

在幕後,編譯器用擴展的調用來替換您的擴展方法的任何調用。

它看起來像你試圖讓C#的行爲,比如Ruby,並通過將一組值初始化對象數組,或者至少模仿詞典初始化的行爲。 不幸的是,如果沒有實際重載列表<>,你不能這樣做。

集合初始化是編譯器魔術只是另一位試圖爲有在參數列表中的項目,以找到儘可能多的參數的Add方法。否則,您可以定義一個轉換操作符將列表轉換爲您的元組類型。

爲什麼不使用內置對象初始值設定項?你只需要編寫更多的代碼

+1

」爲什麼不使用內置對象初始值設定項?您只需要編寫更多代碼「 正確。但我首先使用初始化程序來_reduce_代碼膨脹... – 2011-03-28 12:34:15