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++中,使用 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 包装器。