简体   繁体   中英

C# Passing a part of an array as an argument of a function by reference

Is the C# code below the equivalent way of trying to achieve the same as the C++ code? Is there any way to avoid the copy (while not sending the whole array to the function)?

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

Arrays are reference types. You are not sending the whole array to the function: you are sending a reference to the array.

If you want your function to update only part of that array, pass the start and end indices as parameters.

In C++, use std::vector , and iterator-pair.

And in C#, you could pass the entire array (which is a reference type ) along with a pair of indices signifying begin and end.


C++ code should look like this:

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

That is idiomatic, and follows the Standard library philosophy!


And C# code should look like this:

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

This attempts to imitate C++ style. Nothing wrong with that. However, in C#, it is customary to pass the start index and the count, so you can do the following instead:

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!

The second approach follows the .NET library philosophy. I would with this.

Hope that helps.

You could use an ArraySegment to specify the range of the array. You would still need to interrogate the Array, Count and Offset properties of the ArraySegment though. Still, it provides a convenient wrapper.

The alternative would be to write a full-blown IList wrapper for the array (or ICollection, or some other collection type).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM