3

私は c# 4.0 を使用していますが、.NET Common Library またはその他のライブラリで、次のような署名を持つメソッド ( Socket.ReceiveStream.Readなど)をよく見かけます。

int DoSomethingSuperClever(byte[] buffer, int offset, int count)

意図は常に、それをバッファに渡すことであり、(指定されたオフセットから) count 引数で指定した最大バイト数までそのバッファを埋め、実際に埋められた正確なバイト数を返します。

これは、この状況に対処する私の、非常に単純な方法です。

var data = new byte[0];
var buffer = new byte[1024];
int read;

while ((read = something.DoSomethingSuperClever(buffer,
                                                0,
                                                buffer.Length)) > 0)
{
    int origLength = data.Length;
    var temp = new byte[origLength + read];
    Array.Copy(data, temp, data.Length);
    Array.Copy(buffer, 0, temp, origLength, read);
    data = temp;
}

return data;

すべての配列の作成のために、それはかなりゴミだと思いますが、少なくとも私が思うに、それは正しく機能します。

List<byte>を持っていて、それに追加して、最後にToArrayを実行することについて疑問に思いました...

もちろん、単にAddRangeを呼び出すことはできません。なぜなら、read がバッファーの長さよりも短い場合、ジャンクが追加されるからです ( AddRangeは長さの引数を受け入れないため、常にコレクション全体が追加されます)。それで、そのアプローチを採用すると、for ループと大量のAdd呼び出しが発生することになると思いますが、それは配列のコピーよりもさらに悪いことですよね?

では、専門家の皆さん、これらの種類の通話に対処する最も効率的な方法は何ですか?

4

2 に答える 2