0

以下の C# コードは、C++ コードと同じことを達成しようとする同等の方法ですか? コピーを回避する方法はありますか (配列全体を関数に送信しません)。

C++

static void somefunction(double* v, int nb)
{
//something that will update v[0],v[1], ... v[nb-1]
}

double * myarray=new double[100];
somefunction(&myarray[10],5);
//...
delete [] myarray;

C#

static void somefunction(double[] v, int nb)
{
//something that will update v[0],v[1], ... v[nb-1]
}

double[]  myarray=new double[100];
double[] temp_array=new double[5];
somefunction(temp_array,5);
temp_array.CopyTo(myarray,10);
4

3 に答える 3

3

配列は参照型です。配列全体を関数に送信するのではなく、配列への参照を送信しています。

関数でその配列の一部のみを更新する場合は、開始インデックスと終了インデックスをパラメーターとして渡します。

于 2013-01-31T11:47:49.163 に答える
1

C++ ではstd::vector、 と iterator-pair を使用します。

C# では、配列全体 (参照型) を、begin と end を表すインデックスのペアと共に渡すことができます。


C++ コードは次のようになります。

void f(double *begin, double *end)
{
    for ( ; begin < end; ++begin )
    {
         auto & value = *begin; 
         //etc
    }
}

std::vector<double> v(100);
f(&v[10], &v[10] + 5);

これは慣用的であり、標準ライブラリの哲学に従っています!


C# コードは次のようになります。

void f(double[] v, int begin, int end)
{
    for (  ; begin < end ; ++end )
    {
          //access v[begin]
          //etc
    }
}

double[] v =new double[100];
f(v, 10, 10 + 5);

これは、C++ スタイルを模倣しようとします。それは何も悪いことではありません。ただし、C# では、開始インデックスとカウントを渡すのが通例であるため、代わりに次のようにすることができます。

void f(double[] v, int startIndex, int count)
{
    for (int i = 0 ; i < count ;  ++i, ++startIndex)
    {
          //access v[startIndex]
          //etc
    }
}

double[] v =new double[100];
f(v, 10, 5); //note the difference here!

2 番目のアプローチは、.NET ライブラリの哲学に従います。私はこれでいいでしょう。

それが役立つことを願っています。

于 2013-01-31T11:47:02.983 に答える
1

ArraySegmentを使用して、配列の範囲を指定できます。ただし、ArraySegment の Array、Count、および Offset プロパティを調べる必要があります。それでも、便利なラッパーを提供します。

別の方法は、配列 (または ICollection、またはその他のコレクション型) の本格的な IList ラッパーを作成することです。

于 2013-01-31T11:57:02.903 に答える