1

配列から配列フラグメントを取得する必要があります。Array.Copy() の使用にうんざりしています。new ArraySegment(..).Array は元の [完全な] 配列を返します。以下は私が思いついたものですが、かなり不自由だと思います。これを行うより良い方法はありますか?

class Program
{
    static void Main(string[] args)
    {
        var arr = new ArraySegment<byte>(new byte[5] { 5, 4, 3, 2, 1 }, 0, 2).ArrayFragment();
        for (int i = 0; i < arr.Length; i++)
            Console.WriteLine(i);
        Console.Read();
    }
}

static class Extensions
{
    public static T[] ArrayFragment<T>(this ArraySegment<T> segment)
    {
        var arr = new T[segment.Count];
        Array.Copy(segment.Array, segment.Offset, arr, 0, segment.Count);
        return arr;
    }
}

前もって感謝します。

更新: 上記は単なる例です。
私はメソッドを持っています: byte [] CalculateXXX(byte [] key, byte [] message); このメソッド内で配列操作を行います。配列の一部を返したい。ArraySegment は IEnumerable を実装せず、セグメント new ArraySegment(arr...) だけを含む配列を返しません。Array は完全な元の配列を返します。

var rval = new byte[4]; //new ArraySegment(finalOutputBuffer, 0, 4).SegmentedArray(); Array.Copy(finalOutputBuffer, 0, rval, 0, 4);

配列フラグメントを返すために上記のことをしなければならなかったことがわかりました。[新しい配列として]配列のフラグメントを返すより良い方法があるかどうか疑問に思っていました。

4

3 に答える 3

1

より適切に定義します。ArraySegment の欠点は何ですか? 解決しない問題は何ですか?


編集:わかりました、私はあなたの見方を理解しましたが、これは間違っています. もっとやるべきだと思うという意味ではバグかもしれませんが、やるべきことは正確にやってくれます。使用したい配列と、使用する配列の部分に関する情報をコードに渡すことができます。

IEnumerable や、配列の狭いビューを提供するものは提供しません。x[0] は、セグメントの最初の要素を提供しません。また、それを foreach することもできません。

そうです、それ自体ではかなり役に立ちませんが、本質的に配列でありながら、より大きな配列のセグメントでもあるものを取得することはできません。

配列を参照し、配列をストレージとして使用し、インデックス作成、列挙などを提供する独自のコレクションのようなクラスを簡単に作成できます。

しかし、それはこの構造が行うことではありません。ここでの主な問題は、その名前によって、より多くのことを期待させたことだと思います。

于 2008-12-19T18:11:08.090 に答える
1

Vyas、この役に立たない山を投稿して本当に****申し訳ありません。私が実際に使用してから何年も経ちましたがArraySegment、(多かれ少なかれ)一貫したインターフェースを実装していると単純に思っていました。誰か (Jon?) が、この役に立たない構造体の実装中に使用された薬を教えてください。

最後に、長い話を手短に言うと、最善の解決策はおそらく、独自のバージョンの を実装するArraySegmentことです。

の使用に関する問題がわかりませんArraySegment。元のデータのコピーが行われないため、ここで追加のオーバーヘッドが発生することはありません。むしろ、ArraySegmentデータの軽量ビューを提供します。

これを機能させるには、(戻り) タイプを から に変更するT[]IEnumerable<T>、インデックス付きアクセスが必要な場合は に変更しますIList<T>。一般に、メソッド シグネチャでインターフェイス型を使用することを好み、配列型を完全に避けます。論理的根拠は非常に単純です。これにより、問題が解消され、インターフェイスがより柔軟になり、将来も保証されます。また、このメソッドのコンシューマーに関係のない実装の部分を隠すため、より優れた情報隠蔽も提供します。

于 2008-12-18T23:15:51.600 に答える
0

C#での貧弱なイテレータ設計のもう1つの副作用です。よく似た (「ラメ」のように) 多くの例があります。ここでは、すべての難解なシッカニーなしで、セグメント (別名、範囲と呼ばれる概念) を渡したり、ポイントしたり、制御したりすることができるのは、単純に良い設計です。セマンティクスをコピーするかどうかにかかわらず、配列も同様です。明確に定義された概念。

C++ を使用するだけです。:-)

于 2009-04-13T22:52:34.333 に答える