私は c# 4.0 を使用していますが、.NET Common Library またはその他のライブラリで、次のような署名を持つメソッド ( Socket.Receive、Stream.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呼び出しが発生することになると思いますが、それは配列のコピーよりもさらに悪いことですよね?
では、専門家の皆さん、これらの種類の通話に対処する最も効率的な方法は何ですか?