请考虑以下代码:
abstract class SomeClassX<T>
{
// blah
}
class SomeClassY: SomeClassX<int>
{
// blah
}
class SomeClassZ: SomeClassX<long>
{
// blah
}
我想要SomeClassX&lt; T&gt;的集合,但是,由于SomeClassX&lt; int&gt;,这是不可能的。 != SomeClassX&lt; long&gt;和列表&lt; SomeClassX&lt;&gt;&gt;是不允许的。
所以我的解决方案是让SomeClassX&lt; T&gt;实现一个接口并定义我的集合,其中ISomeClassX是接口:
class CollectionOfSomeClassX: List<ISomeClassX>
{
// blah
}
这是最好的方法,还是有更好的方法?
答案 0 :(得分:1)
我要么使用你建议的界面,要么让SomeClassX从另一个类继承。这实际上取决于您需要对集合中的对象执行的操作。无论它们具有哪些共同功能,都应该使用基类或接口,如果这看起来更合适的话。
答案 1 :(得分:1)
您最好的选择是按照您的建议,创建一个界面ISomeClass
并实施它。我最近使用用户首选项和配置文件系统解决了同样的问题,我们希望用它来存储各种数据类型。它归结为:
public interface IEntry
{
// ...
object Value { get; set; }
}
可以实例化特定Entry<Single>
,因为Entry<T>
隐式实现了接口:
public class Entry<T> : IEntry
{
T Value { get; set; }
object IEntry.Value { get { return Value; } set { return Value; } }
}
但是当IDictionary<string,IEntry>
时,我们又将IEntry
个实例转换为适当类型的Entry<T>
实例或IEntry
的Value属性
// assume entries is IDictionary<string,IEntry>...
var entry = entries["pizza-weight"];
var weight = (float)entry.Value;
当然,这一切都有道理,因为正如SomeClass<int>
!= SomeClass<long>
所以这是真的IList<SomeClass<int>>
!= IList<SomeClass<long>>
。