如何只暴露IList <>的片段?

时间:2020-03-05 18:46:25  来源:igfitidea点击:

我有一个通过公开内部IList <>的类属性

System.Collections.ObjectModel.ReadOnlyCollection<>

如何在不将元素复制到新数组的情况下传递此ReadOnlyCollection <>的一部分(我需要实时显示,并且目标设备内存不足)?我的目标是Compact Framework 2.0。

解决方案

回答

在转换索引之后,我们始终可以编写一个实现IList并将所有调用转发到原始列表的类(这样它就没有它自己的数据副本)。

回答

我们可以使用yield return创建过滤列表

IEnumerable<object> FilteredList()
{
    foreach( object item in FullList )
    {
        if( IsItemInPartialList( item )
            yield return item;
    }
}

回答

如何访问已过滤的元素?如果是通过Iterator进行的,那么我们也许可以编写一个自定义的Iterator来跳过不需要公开显示的元素?

如果我们需要提供一个Collection,则可能需要编写自己的Collection类,该类仅作为基础Collection的代理,但是阻止访问我们不想公开可见的元素。

(免责声明:我对C#不太熟悉,所以这些是一般性的答案。对于C来说,可能有更具体的答案更有效)

回答

尝试使用yield返回枚举的方法:

IEnumerable<T> FilterCollection<T>( ReadOnlyCollection<T> input ) {
    foreach ( T item in input )
        if (  /* criterion is met */ )
            yield return item;
}

回答

根据我们需要如何过滤集合,我们可能想要创建一个实现IList(或者IEnumerable,如果适用的话)的类,但该类与索引和访问无关,只能返回所需的值。例如

class EvenList: IList
{
    private IList innerList;
    public EvenList(IList innerList)
    {
         this.innerList = innerList;
    }

    public object this[int index]
    {
        get { return innerList[2*i]; }
        set { innerList[2*i] = value; }
    }
    // and similarly for the other IList methods
}

回答

这些foreach示例很好,但是如果使用.NET 3.5和LINQ,则可以使它们更简洁:

return FullList.Where(i => IsItemInPartialList(i)).ToList();