具有相同“原始类型”但不同类型参数的对象集合

时间:2014-12-13 02:35:59

标签: c# generics

在Java中,您可以编写一个静态方法来反转集合中的每个List

public static void reverseAll(Collection<List<?>> lists) {
    for (List<?> list : lists)
        Collections.reverse(list);
}

当我尝试在C#中进行类似的操作时,我遇到了困难,因为IList<T>作为T的接口不同,不会与Reverse方法共享一个公共接口。我发现您可以使用dynamic类型执行此操作:

public static void ReverseAll(IEnumerable<dynamic> lists)
{
     foreach (dynamic list in lists)
        list.Reverse();
}

我不喜欢这种方法,因为没有什么可以阻止你传入IEnumerable ILists并且你失去所有编译时检查。对这类事情有更好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

使用T

的标记界面
public static void ReverseAll<T>(IEnumerable<List<T>> lists) where T : YourMarkerInterface

然后将界面应用于您馆藏中的所有T

答案 1 :(得分:0)

理想情况下,包含不关心泛型类型的成员的通用接口 - 而不是直接实现这些成员 - 从提供它们的非泛型基接口继承。例如,IList<T>可以继承自IPermutableSequence接口,其中包含CountReverseSwapRotateRange等方法。 IList<T>来自这样一个基础,你所寻求的行为可以很容易地实现。

不幸的是,如果集合中的东西实现了非协变且没有有用的公共基类型的通用接口,那么就没有很好的方法来实现您所寻求的行为。相反,有必要对每个对象实例的类型使用Reflection来确定它是否为List<>,如果是,则提取泛型类型参数并使用它来生成和调用ListReverse<T>方法。并非完全不可能,但icky。

由于您尚未描述实际使用场景,因此不清楚是否有可能将非泛型方法提取到非泛型接口并使用它。这种方法比使用Reflection的方法更快更干净。