【问题标题】:Limited IList<> implementation?有限的 IList<> 实现?
【发布时间】:2010-04-12 09:59:27
【问题描述】:

我正在做一些统计工作,并想重构以下方法:

public static blah(float[] array)
{
    //Do something over array, sum it for example.
}

但是,我不想使用 float[],而是希望使用某种索引可枚举(例如,使用从磁盘动态加载非常大的数组)。 我创建了一个简单的界面,并想使用它。

public interface IArray<T> : IEnumerable<T>
{
    T this[int j] { get; set; }
    int Length { get; }
}

我的问题是:

  • float[] 只继承 IList,而不是 IArray,而且 AFAIK 没有办法改变它。
  • 我想放弃 IArray 而只使用 IList,但是我的类需要实现许多方法,例如 AddRemoveAt,尽管它们是固定大小的
  • 然后我的问题是:如果 float[] 没有这些方法,如何实现 IList?

欢迎任何帮助。 干杯

【问题讨论】:

    标签: c# arrays ilist


    【解决方案1】:

    float[] 只继承 IList,而不是 IArray,而且 AFAIK 没有办法改变它。

    Array of T 还实现了 IList&lt;T&gt; 和其他(但这些并不总是显示在工具中,Array 的几个方面作为运行时的特殊情况)。

    我想放弃 IArray 而只使用 IList,但我的类需要实现许多方法[...]

    确实如此,但这样的实现非常快(如果您只需要非修改操作,您可以从修改方法中抛出NotImplementedException)。

    在实践中只需几分钟即可完成,并且您的实现应该是可重用的。还有像ReadOnlyCollection&lt;T&gt; 这样的类型可以帮助避免很多这样的工作。

    然后我的问题是:float[] 没有这些方法,如何实现 IList?

    一个类型可以显式地实现接口方法。它们不是类型的直接成员,但转换为接口(或反射)将允许访问。这允许类型化集合实现IEnumerator.Current(返回Object),同时还提供返回正确类型的Current 属性。

    【讨论】:

    • 认为你的意思是明确的,而不是含蓄的
    • @Sekhat:我确实做到了。已更正。
    • 嗯,谢谢,你让我知道了显式/隐式接口方法实现之间的区别。
    【解决方案2】:

    事实上,float[] array 确实实现了IList&lt;float&gt;

    var floats = new[] { 1.0f, 2.0f, 3.5f };
    var list = (IList<float>)floats;
    

    这是19.6:

    一维数组S[] 实现了接口System.Collections.Generic.IList&lt;S&gt;(简称IList&lt;S&gt;)及其基本接口。因此,存在从 S[]IList&lt;S&gt; 及其基接口的隐式转换。

    【讨论】:

    • 我知道,我的问题是它如何实现 IList 和 ICollection 而不实现 ICollection/IList 中的 Add、RemoveAt 和这些其他方法?
    【解决方案3】:

    我最终写了以下内容: 公共类 IArrayWrapper : IArray { 私有浮点[] 内部数组;

        public IArrayWrapper(float[] array)
        {
            innerArray = array;
        }
    
        public static implicit operator float[](IArrayWrapper wrapper)
        {
            return wrapper.innerArray;
        }
    
        public static implicit operator IArrayWrapper(float[] array)
        {
            return new IArrayWrapper(array);
        }
    
        public IEnumerator<float> GetEnumerator()
        {
            return ((IEnumerable<float>) innerArray).GetEnumerator();
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return innerArray.GetEnumerator();
        }
    
        public float this[int j]
        {
            get { return innerArray[j]; }
            set { innerArray[j] = value; }
        }
    
        public int Length
        {
            get { return innerArray.Length; }
        }
    }
    

    我对此并不感到自豪,但我认为隐式运算符应该可以解决我的问题......希望。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-13
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      相关资源
      最近更新 更多