好的,情况是这样的。我有一个 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> { };
问题是ExtendedItem
是 FlexItem<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/