【问题标题】:Best practice for a collection of generic classes泛型类集合的最佳实践
【发布时间】:2010-09-18 15:34:06
【问题描述】:

考虑以下代码:

abstract class SomeClassX<T>
{
  // blah
}

class SomeClassY: SomeClassX<int>
{
  // blah
}

class SomeClassZ: SomeClassX<long>
{
  // blah
}

我想要 SomeClassX 的集合,但是,这是不可能的,因为 SomeClassX != SomeClassX 和 List> 是不允许的。

所以我的解决方案是让 SomeClassX 实现一个接口并将我的集合定义为,其中 ISomeClassX 是接口:

class CollectionOfSomeClassX: List<ISomeClassX>
{
  // blah
}

这是最好的方法,还是有更好的方法?

【问题讨论】:

    标签: .net generics collections


    【解决方案1】:

    您最好的选择是按照您的建议,创建一个接口ISomeClass 并实现它。我最近用一个用户偏好和配置文件系统解决了同样的问题,我们想用它来存储各种数据类型。归结为:

    public interface IEntry
    {
        // ...
        object Value { get; set; }
    }
    

    特定的Entry&lt;Single&gt; 可以被实例化,因为Entry&lt;T&gt; 隐式实现了接口:

    public class Entry<T> : IEntry
    {
        T Value { get; set; }
        object IEntry.Value { get { return Value; } set { return Value; } }
    }
    

    但是当涉及到IDictionary&lt;string,IEntry&gt; 时,我们又将IEntry 实例转换为Entry&lt;T&gt; 适当的类型或IEntry 的Value 属性转换为适当的类型。

    // assume entries is IDictionary<string,IEntry>...
    var entry = entries["pizza-weight"];
    var weight = (float)entry.Value;
    

    当然,这一切都是有道理的,因为就像 SomeClass&lt;int&gt; != SomeClass&lt;long&gt; 一样,IList&lt;SomeClass&lt;int&gt;&gt; != IList&lt;SomeClass&lt;long&gt;&gt; 也是如此。

    【讨论】:

    • 我曾想过这个,但放弃了这个想法,因为访问项目时需要强制转换。不妨使用旧的 System.Collections :-)
    【解决方案2】:

    我要么使用你建议的接口,要么让 SomeClassX 从另一个类继承。这实际上取决于您需要对集合中的对象做什么。无论它们有什么共同的功能都应该放在基类中,或者如果看起来更合适的话,应该放在接口中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-06
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2016-09-03
      • 2019-04-13
      相关资源
      最近更新 更多