C#通过引用传递数组的一部分作为函数的参数

时间:2013-01-31 11:42:57

标签: c# c++

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);

3 个答案:

答案 0 :(得分:3)

数组是引用类型。您没有将整个数组发送到函数:您正在发送对数组的引用。

如果希望函数只更新该数组的一部分,请将开始和结束索引作为参数传递。

答案 1 :(得分: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库哲学。我愿意这样做。

希望有所帮助。

答案 2 :(得分:1)

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

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