2012-08-24 52 views
0

創建的 列表我有一個名爲SCO,一些類繼承的基類。我最初只是想對這個集合進行排序,但是根據一些建議,聽起來我可以用一種方法實例化和排序集合。 從基類

我有這樣的構造,所有的基類繼承:

public SCO(SPListItem item, List<Vote> votes) 
{ 
    UpVotes = voteMeta.UpVotes; 
    DownVotes = voteMeta.DownVotes; 
    VoteTotal = UpVotes - DownVotes; 
    HotScore = Calculation.HotScore(Convert.ToInt32(UpVotes), Convert.ToInt32(DownVotes), Convert.ToDateTime(item["Created"])); 
} 

這是我卡住。我無法實例化<T>

public static List<T> SortedCollection<T>(SPListItemCollection items, ListSortType sortType, List<Vote> votes) where T : SCO 
{ 
    var returnlist = new List<T>(); 
    for (int i = 0; i < items.Count; i++) { returnlist.Add(new T(items[i], votes)); } 
    switch (sortType) 
    { 
     // Sort List based on passed ENUM 
    } 
    return returnlist; 
} 

如果我能做到這一切在一個方法,我避免了一些昂貴的鑄造和拳擊。

+0

你爲什麼不能使用?你會得到什麼錯誤? – carlosfigueira

+1

除非存在新約束,否則不能實例化泛型類型參數,並且允許添加的唯一新約束是無參數構造函數。請參閱:http://msdn.microsoft.com/en-us/library/sd2w2ew5.aspx –

+0

無法創建類型參數'T'的實例,因爲它沒有new()約束。 – Wesley

回答

3

仿製藥的唯一限制是允許new(),其中如果有不帶任何參數的構造函數纔有效。

我有這樣的構造,所有的基類繼承:

的問題是,這不是強制執行。子類是(也應該是)可以自由定義自己的構造函數,只要它們鏈接到這個構造函數。一個子類可以自由地使用實例化該類所需的任何構造機制。

您可以解決此通過反射和Activator.CreateInstance,這將讓你構造對象與參數。然而,這是相當「難看」(雖然不是醜陋的考慮,使用new() constraint still calls Activator.CreateInstance):

Type genericType = typeof(T); 
for (int i = 0; i < items.Count; i++) 
{ 
    returnlist.Add((T)Activator.CreateInstance(genericType, new object[] {items[i], votes})); 
} 
2

缺少了什麼這裏的東西比你的手段用於實例T對象更通用:

new T(items[i], votes) 

編譯器無法保證,此構造存在每個類型T。你可能做的是有函數接受作爲附加參數Func<SPListItem, IList<Vote>, T>類型的一些工廠方法,使上述可改寫:

returnlist.Add(factory(items[i], votes)) 

另外,還可以代替有效地實現工廠類包含此實例化邏輯,在你的代碼從SCO派生每種類型,如:

class SCOFactory 
{ 
    public T Create<T>(SPListItem item, IList<Vote> votes) where T : SCO 
    { 
     // Do your instantiation here. 
    } 
} 

你看這個了很多(它通常被稱爲「工廠模式」);作爲一種方法(通常是一個巨大的switch聲明),它可能有點醜陋,但至少它包含了一個地方的醜陋,並允許您編寫諸如問題中的函數,而無需添加其他參數並最終混亂你項目中的很多代碼。

一般一個忠告(採取與一粒鹽,當然):過於一般化你的代碼最終會導致頭痛而沒有得到太多實惠。在繼續之前先問自己,以這種通用的方式編寫這些代碼對您是否有益;如果是這樣,上述任何一種建議都可能證明是一個體面的起點。如果沒有,可以考慮採用更簡單的方法,理論上可能不太靈活,但更容易在實踐中使用。

0

需要在構造函數中傳遞這些值嗎?

你可以把對這些類型可設置屬性,然後調用默認的構造函數,並且在創建對象後,剛剛成立的屬性後...