从基类</t>创建<t>列表

时间:2012-08-24 23:44:28

标签: c# generics inheritance instantiation

我有一个名为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;
}

如果我可以用一种方法完成所有这些操作,我可以避免一些昂贵的施法和装箱。

3 个答案:

答案 0 :(得分: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})); 
}

答案 1 :(得分: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语句),但至少它包含一个地方的丑陋,并允许你编写函数,如问题中的函数,而不必添加另一个参数并最终混乱了项目中的大量代码。

一句普遍谨慎的话(当然要采取一些措辞):过度泛化你的代码最终会导致头痛而不会产生太多实实在在的好处。在继续之前问问自己,以这种通用方式编写此代码对您是否真有益;如果是这样,上述任何一个建议都可能是一个不错的起点。如果没有,考虑采用一种更简单的方法,理论上可能不那么灵活,但在实践中更容易使用。

答案 2 :(得分:0)

需要在构造函数中传递这些值吗?

你可以在类型上创建那些可设置属性,然后调用默认构造函数,在创建对象之后,只需在...之后设置属性。

相关问题