C# 泛型通配符或如何保存对未知泛型继承的引用

标签 c# generics inheritance wildcard

好的,情况是这样的。我有一个 FlexCollection<T>类,其目的是保存 FlexItem 的一些专业列表,因此:

public class FlexCollection<T> where T : FlexItem, new()
{
    public void Add(T item) { ... }
    ...
}

FlexItem不是泛型类本身。我想要实现的是能够保持 FlexItem的字段是对包含该对象的集合的引用。不幸的是,在 C# 中,不可能保留对模板类的“任何”特化的引用(如在 Java 中)。起初我尝试使用非通用接口(interface) IFlexCollection但它实际上迫使我对每个方法执行两次,即:

public class FlexCollection<T> : IFlexCollection where T : FlexItem, new()
{
    public void Add(T item) { ... } // to use in generic calls
    public void Add(object item) { ... } // to use for calls from within FlexItem
    ...
}

然后我发现我可以使 FlexItem 本身成为一个通用类!然后一个特化可以持有对该特化对象集合的引用(这是很合乎逻辑的)。因此:

public class FlexItem<T> where T : FlexItem<T>, new()
{
    public FlexCollection<T> ReferenceToParentCollection;
    ...
}

public class FlexCollection<T> where T : FlexItem<T>, new()
{
    public void Add(T item) { ... } 
    ...
}

现在我可以申报一些FlexItem<T>特化和相应的集合:

public class BasicItem : FlexItem<BasicItem> { public int A; }
public class BasicCollection : FlexCollection<BasicItem> { };

当我尝试扩展这些类以容纳额外的字段时,问题就出现了。 IE。我想要一个 ExtendedItem拥有领域的类(class)B除字段A :

public class ExtendedItem : BasicItem { public int B; }
public class ExtendedCollection : FlexCollection<ExtendedItem> { };

问题是ExtendedItemFlexItem<BasicItem> 的子类而不是 FlexItem<ExtendedItem> .因此不可能申报ExtendedCollection如上。这会导致编译错误:

The type 'Demo.ExtendedItem' must be convertible to
'Demo.FlexItem<Demo.ExtendedItem>' in order to use it as parameter 'T'
in the generic type or method 'Demo.BasicCollection<T>'

有什么办法可以避免这种类型冲突吗?

最佳答案

好的,我决定尝试一下 C# 事件。这样我实际上不需要 FlexItem 来保存对拥有 FlexCollection 的引用。如果执行相应的操作,我只是引发一个事件,即“IAmBeingRemoved”和 FlexCollection 的代码。代码逻辑甚至被更好地封装了。我只是希望我不会遇到任何性能问题或其他基于通用的惊喜。 :-) 我发布它是为了让有人发现它是解决他们自己问题的好方法。

关于C# 泛型通配符或如何保存对未知泛型继承的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11234903/

相关文章:

c# - 'base' 和 'this' 在引用父对象字段、属性或方法时有区别吗?

generics - Java 8 泛型方法...不适用于 Eclipse 中的参数

delphi - 如何覆盖继承的属性?

c++ - 如何使一个函数的返回类型与另一个函数的返回类型相同?

c# - 我对类、对象和实例有点困惑

c# - C#(或C++)与JAVA之间如何通信

java - 如何改进 Java 泛型通配符签名

java - 泛型的代码模型狭窄

Java继承问题

c# - Xamarin iOS - 屏幕流程