如何在C#中使用泛型类型来获取类方法?

时间:2014-11-24 22:37:44

标签: c# generics inheritance generic-programming

假设我正在构建一个通用的Table<T>类。以下是我对容器的要求:

  • 类型T必须是引用(或可以为空,取决于您喜欢的)类型,才能使用null代替T。这给了我where T: class约束。
  • 类型T必须为IComparable,因为我想比较表中的值,这给了我where T : IComparable的另一个约束。 (可能有更多的接口限制。)
  • 泛型类型必须能够专门用于接口,这意味着我无法进一步限制它继承某些特定的(甚至是抽象的)类。

总之,该表将定义为class Table<T> where T: class, IComparable。我还需要创建一个代表默认的T实例。 默认并不一定只是默认值,可能有两个不同的默认值,只需将其视为为给定类型创建一些有代表性的预定义值T (这也可能是最大/最小值。)

重申我的最后一点,我希望能够使用它来存储不共享父母的类型。例如,请考虑以下类型层次结构

         A
       / | \
      B  C  D

现在让我们说我只想存储类型BC,而不是其他内容。 ad-hoc解决方案是将类层次结构更改为如下所示

         A
       /  \
      E    D 
     / \
    B   C

现在你可以说我可以使用Table<E>。但是如果课程BC完全不相关怎么办?或者他们可能已经处于自己的继承层次结构中,只是分享了一个常见的事实,即它们需要存储在此表中。

可能的解决方案但不理想

这个问题的解决方案是定义一个他们都将实现的接口,并将其用作泛型类型专门化。例如

class A {}
class B : A, IStorable {}
class C : A, IStorable {}
class D : A {}

interface IStorable {}

通过此界面,我现在可以轻松地执行Table<IStorable>并确保只有BC类型存储在表格中,这很棒。但这就是我陷入困境的地方。使用界面,我不再有办法说表中存储的类型应该能够创建默认值。在这种特殊情况下,IStorable的默认值可能是new B(42),但我无法在通用Table<T>中表达,因为它对我的类型一无所知{ {1}}。如果我可以说T必须实现静态方法,那可以用作工厂方法,这将解决问题,但静态方法不能放在C#中的接口中,所以这也是不可能的。

我到目前为止找到的唯一解决方法是T有一个构造函数接受Table<T>,这是一个可以创建默认值的函数,但这也是非常特别的。只是为了弄清楚它会是什么样子

Func<T>

是否有更好的使用通用的方式,以便我可以创建class Table<T> where T: class, IComparable, IStorable { Table(Func<T> factory) { ... } } 类型的实例,同时还允许T成为接口?只是免责声明,T运算符不够好,因为它只返回default作为引用类型,并且需要通过null的无参数构造函数也不够好,因为这不允许我要在接口类型上专门化where T : new()

0 个答案:

没有答案
相关问题