配列型引数を受け取るときのガイドライン

世の中,失って初めて気付くことというのがあります.以下はC++でのDrawPrimitiveUPメソッドとMDXでのDrawUserPrimitivesメソッドの宣言の比較です.MDXのDrawUserPrimitivesメソッドはこれ以外にオーバーロードを持ちません.そのためC++では当然のように出来ていたあることがMDXではできなくなっているのですが,お気づきになりましたでしょうか?

// C++
HRESULT DrawPrimitiveUP(
    D3DPRIMITIVETYPE PrimitiveType,
    UINT PrimitiveCount,
    const void *pVertexStreamZeroData,
    UINT VertexStreamZeroStride
);

// C#
public void DrawUserPrimitives(
    PrimitiveType primitiveType,
    int primitiveCount,
    object vertexStreamZeroData
);

MDXで失われてしまったもの,それはある頂点配列の任意の部分頂点配列を描画するための手段です.C++ではpVertexStreamZeroData引数に適当なオフセットを与えることで容易に描画先頭位置を変更することが可能でした.しかし,.NETにおける配列というのは基本的に固定長のオブジェクトとして扱われるため,部分配列はコピーによってしか作ることが出来ません.このコピーを回避するためには,配列はそのまま引数に取りながら,別の引数で先頭インデックスも取るようなメソッドを作る必要があります.
このような視点で .NET Base Class Library を眺めてみると,実に多くのクラスでこのような先頭インデックスを指定可能なオーバーロードが提供されていることに気付きます.例としてArray.Copyメソッドのオーバーロード一覧を挙げておきましょう.
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemarrayclasscopytopic.asp
DrawUserPrimitives が先頭インデックスを引数に取るオーバーロードを提供していないのは,.NETという世界の常識から見れば設計的なミスの1つと言えるでしょう.