【发布时间】:2020-12-29 12:17:27
【问题描述】:
我正在使用一个库,其中包含(数百个模板生成的)没有泛型修饰符的类,每个类都使用泛型修饰符扩展相同的类(本质上是为了缩短符号)。例如
class DArr : NumberObject<double, MyArrayIndexer> { ... }
class IArr : NumberObject<int, MyArrayIndexer> { ... }
class DMat : NumberObject<double, MyMatrixIndexer> { ... }
class IMat : NumberObject<int, MyMatrixIndexer> { ... }
class BMat : NumberObject<bool, MyMatrixIndexer> { ... }
and so on
我现在想编写一个函数来处理这些函数,该函数需要它们的内部类型(例如,需要知道每个元素是 4 字节还是 8 字节,以及正在使用什么类型的索引器的内部副本)。因此,我对我的函数进行了签名:
public SomeUnrelatedClass<T> Process<T,TVal,T0>(SomeUnrelatedClass<T> obj) where T : NumberObject<TVal,T0> {
//here some tstuff that requires T, TVal and T0
}
但不幸的是,我似乎无法以我需要的方式使用它,即
SomeUnrelatedClass<DArr> input = ...;
SomeUnrelatedClass<DArr> output = Process(input);
因为它无法从(为什么??)推导出 TVal 和 T0,尽管它是唯一确定的。我该如何补救?将其称为SomeUnrelatedClass<DArr> output = Process<DArr,double,MyArrayIndexer>(input); 不是一种选择,因为实际上这些泛型有很多而且它们的名称也更长(而且这个函数将在未来的代码中使用数千次,所以我宁愿现在编写一个更复杂的函数,使其正确并保持语法简单)。理想情况下,我不会做一长串“if type == ...”,因为类型列表是模板生成的,并且随着类型的添加会随着时间的推移而变化(这意味着这个模板将依赖于另一个模板,等等)
我想到了一些愚蠢的技巧,比如制作语法Process<T,TVal,T0>(SomeUnrelatedClass<T> obj,SomeUnrelatedClass<NumberObject<TVal,T0>> sameObj) 和调用SomeUnrelatedClass<DArr> output = Process(input,input);,但我觉得这只是一个非常糟糕的解决方案。有什么更“正确”的方法来做到这一点?
【问题讨论】:
-
我知道支持这一点的语言,但 C# 不是其中之一。您将不得不考虑变通办法。
-
你想得到
doubleMyArrayIndexer的字符串class DArr : NumberObject<double, MyArrayIndexer>? -
我已经向 ahybertz 答案添加了一条评论,它可以为您提供您想要的。试试这个签名:
public static SomeUnrelatedClass<T> Process<T, TVal, T0>(T input) where T : NumberObject<TVal, T0>. -
你能把
Process方法移到SomeUnrelatedClass类吗?因为它显然知道所有类型是什么。
标签: c# generics inheritance