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

您可以使用ArraySegment来指定数组的范围。不过,您仍然需要询问 ArraySegment 的 Array、Count 和 Offset 属性。尽管如此,它还是提供了一个方便的包装器。

另一种方法是为数组(或 ICollection 或其他一些集合类型)编写一个成熟的 IList 包装器。

于 2013-01-31T11:57:02.903 回答
1

在 C++ 中,使用std::vector, 和迭代器对。

在 C# 中,您可以传递整个数组(这是一个引用类型)以及一对表示开始和结束的索引。


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!

第二种方法遵循 .NET 库理念。我会用这个。

希望有帮助。

于 2013-01-31T11:47:02.983 回答