Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有“相同”属性的对象集合;“原始类型”;但类型参数是可变的_C#_Generics - Fatal编程技术网

C# 具有“相同”属性的对象集合;“原始类型”;但类型参数是可变的

C# 具有“相同”属性的对象集合;“原始类型”;但类型参数是可变的,c#,generics,C#,Generics,在Java中,您可以编写一个静态方法来反转集合中的每个列表: public static void reverseAll(Collection<List<?>> lists) { for (List<?> list : lists) Collections.reverse(list); } 我不喜欢这种方法,因为没有任何东西可以阻止您传递不包含ILists的IEnumerable,并且您会丢失所有编译时检查。有更好的解决方案吗?为T使

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

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

我不喜欢这种方法,因为没有任何东西可以阻止您传递不包含
ILists
IEnumerable
,并且您会丢失所有编译时检查。有更好的解决方案吗?

为T使用标记接口

public static void ReverseAll<T>(IEnumerable<List<T>> lists) where T : YourMarkerInterface
publicstaticvoidreverseall(IEnumerable列表),其中T:YourMarkerInterface

然后将接口应用于集合中可能存在的所有T,理想情况下,包含不关心泛型类型的成员的泛型接口将继承提供这些成员的非泛型基接口,而不是直接实现这些成员。例如,
IList
可能继承自
IPermutableSequence
接口,该接口包括
Count
Reverse
Swap
RotateRange
等方法。如果
IList
是从这样一个基础派生出来的,那么您所寻求的行为可能很容易实现

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


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

出于好奇,您将多个T的列表集合传递到一个方法中以反转每个单独列表的用例是什么?好问题!我没有。这只是一个例子来说明我遇到的一个问题。实际上,我已经创建了一个最近删除的T类型项目的通用类Bin,并创建了一个方法Restore来恢复它们。我希望我的应用程序具有“全部还原”按钮。在Java中,这很容易,但在C中,如果类型可以不同,则似乎要复杂得多。你可以选择
对象
而不是
动态
,但在复杂时间检查方面几乎没有任何改进。我知道这不是你真正想要的,但是对于数组,它不是真正的泛型,您可以这样做:
publicstaticvoidreverseall(IEnumerable列表){foreach(列表中的数组列表){Array.Reverse(列表);}}
谢谢。我发布这个问题只是为了确认你基本上不能以任何好的方式来做这件事——我很惊讶它花了这么长时间!我对Java非常熟悉,以至于与C#的差异需要一段时间才能适应。@pbabcdefp:在一些地方,类型擦除是有帮助的,尽管大多数都可以通过使用与类型无关的接口来处理。例如,如果存在一个
ITypedList
接口,该接口包含一个
TryAdd(Object o)
方法,该方法将指示是否可以添加所讨论的对象,如果
IList
继承自该方法,人们可以使用
ITypedList
来处理Java的
列表
所能做的一切。我同意这有时是有帮助的,但在运行时无法访问类型信息这一事实非常令人恼火。我打赌每个试图用java编写泛型方法的人都至少写一次
T.class
。不过,我最喜欢的java实现结果是,您可以使用非泛型静态方法,因为类
GenericType
实际上都是相同的。@pbabcdefp:.NET方法好99.44%,除非接口的设计者未能让他们继承一个非泛型接口,该接口包含所有不应该关心泛型类型的方法。不幸的是,如前所述,.NET framework中的大多数通用接口在这方面相当有限。
public static void ReverseAll<T>(IEnumerable<List<T>> lists) where T : YourMarkerInterface