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

本文关键字:一部分 函数 参数传递 数组 引用 | 更新日期: 2023-09-27 17:57:02

下面的 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);

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

数组

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

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

在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 库理念。我会的。

希望有帮助。

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

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