3

メッシュデータ構造を設定するために、このようなことができるようにしたいと思います。

IReadOnlyList<Point> points;
IReadOnlyList<IReadOnlyList<int>> triangles;

ここで、三角形はポイント リストのインデックスです。三角形 ''ti'' のインデックスが与えられると、点を簡単に見つけることができます

IEnumerable<Point> points = triangles[ti].Select(pi=>points[pi])

ただし、便利な構造を定義できるようにしたいと思います

IReadOnlyList<IReadOnlyList<Point>> trianglesAsPoints;

だから私はできる

IEnumerable<Point> points = triangles[ti]

これを行う明白な方法は、linq のようなセレクターを作成することです。

IReadOnlyList<T> Select( this IReadOnlyList<U> This
                             , Func<U,T> selector)

クラスが次のメソッドをオーバーライドし、セレクターを呼び出すインスタンスを返します

public interface IReadOnlyList<out T> : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
{
    // Summary:
    //     Gets the element at the specified index in the read-only list.
    //
    // Parameters:
    //   index:
    //     The zero-based index of the element to get.
    //
    // Returns:
    //     The element at the specified index in the read-only list.
    T this[int index] { get; }
}

このようなファクトリは、このパターンの標準ライブラリまたはナゲットのどこかに存在しますか? インデックス作成機能と Count プロパティが失われるため、結果として IEnumerable は必要ないことに注意してください。値を遅延変換したいだけです。つまり 、すべての値を新しいリストインスタンスに事前にコピーしないことを意味します。

4

2 に答える 2

1

これが問題に対する手動の解決策です

public static class CollectionMixins
{
    private class ReadOnlyListProjection<U,T> : IReadOnlyList<T>
    {

        public Func<U,T> Selector { get; private set; }
        public IList<U> List { get; private set; }

        public ReadOnlyListProjection(IList<U> list, Func<U, T> selector)
        {
            List = list;
            Selector = selector;
        }

        public T this[int index]
        {
            get { return Selector(List[index]);  }
        }

        public int Count
        {
            get { return List.Count; }
        }

        public IEnumerator<T> GetEnumerator()
        {
            return List.Select(Selector).GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return List.Select(Selector).GetEnumerator();
        }
    }

    public static IReadOnlyList<T> ProjectReadOnly<U, T>(this IList<U> This, Func<U, T> fn)
    {
        return new ReadOnlyListProjection<U, T>(This, fn);
    }
}

だから私は今できる

IList<int> foo = new List<int>{0,1,2};
IReadOnlyList<string> bar = foo.ProjectReadOnly( x=>x.ToString() );
于 2013-03-13T07:49:14.987 に答える