How did the code reach the link pass?

Inside main, I have declared a local array int [] (int [] nums). I didn't pass it by link. But when I print the values โ€‹โ€‹of the local array, I get the square of the value of each element. What is the reason for this?

delegate void tsquare(int[] a);

static void Main()
{
     int[] nums = { 1, 2, 3 };
     tsquare sqr = new tsquare(SomeClass.Square);
     sqr(nums);

     foreach (int intvals in nums)
     {
       Console.WriteLine(intvals);
     }
}


   class SomeClass
   {

     public static void Square(int[] array)
     {
         for (int i = 0; i < array.Length; i++)
         {
             array[i] = array[i] * array[i];
         }
     }

   }

      

Update:

My addictions to everyone. What do I know? int [] {Array} is a value type and the delegate did some tricks on it. Now from your answer, I understand that Array is a reference type.

+2


source to share


7 replies


There are two concepts here.

  • Reference types and value types
  • Passing by value versus passing by reference

Allow the second one first.

Passing something by value means that you are giving a method its own copy of that value, and it is free to change that value, but it doesn't want those changes not to be pushed back into code called the method.

For example, this:

Int32 x = 10;
SomeMethod(x); // pass by value

      

In this case there will be no x there will be nothing but 10 after the call returns in this case, since some SomeMethod did with its copy of the value, it did only its value.

However, passing by reference means that we are not really giving the method its own value to play with, instead we are giving it the memory location where our own value is, and therefore whatever that method does with that value will be reflected in our code because there is actually only one value in the game.

So this:

Int32 x = 10;
SomeMethod(ref x); // pass by reference

      

In this case, x may have a different meaning after SomeMethod returns than before it was called.

Thus, passing by value versus passing by reference.

And now confuse the waters. There's a different concept, reference types and value types that confuse many. Your question hints that you are confused about this issue too, my apologies if you didn't.

The link type is actually part of two parts. This is a link and it is independent of the link. Think of a house where you know the address. You write the address on a piece of paper, you don't really put the whole house on that paper, rather you have a "link" to that particular house on your piece of paper.

The link type in .NET is the same thing. Somewhere in memory, there is an object that is a collection of values โ€‹โ€‹grouped together. The address of this object that you store in a variable. This variable is declared as a type, which is a reference type that allows this two-part transaction.



The good thing about reference types is that you can have many references to the same actual object, so even if you copy the reference around, you only have one object left in memory.

Edit . As for the question, an array is a reference type. This means that your variable only contains the address of the actual array, and that array object is somewhere else in memory.

The value type, however, is one, the whole value is part of the "value type", and when you make copies of that, you make different copies

Here's an example of value types:

struct SomeType
{
    public Int32 Value;
}

SomeType x = new SomeType;
x.Value = 10;
SomeType y = x; // value type, so y is now a copy of x
y.Value = 20; // x.Value is still 10

      

However, with a reference type, you don't make a copy of the object it refers to, only a reference to it. Consider copying the address of this house onto a second piece of paper. You only have one house left.

So, just by changing the SomeType as a reference type (changing struct

to class

):

class SomeType
{
    public Int32 Value;
}

SomeType x = new SomeType;
x.Value = 10;
SomeType y = x; // reference type, so y now refers to the same object x refers to
y.Value = 20; // now x.Value is also 20, since x and y refer to the same object

      

And now for the last thing; passing a reference type by value.

Take this method:

public void Test(SomeType t)
{
    t.Value = 25;
}

      

Given our version of the SomeType class above, we have a method here that takes a reference type parameter, but it takes it as passed by value.

This means that Test cannot change t

to refer to another object altogether and make that change back to the calling code. Think about it by calling a friend and giving him the address you have on a piece of paper. No matter what your friend does with this house, the address you have on paper will not change.

But this method is free to change the contents of the object it refers to. In this home / friend scenario, your friend can go and visit that home and rearrange furniture. Since there is only one house in the game, if you go to that house after regrouping it, you will see its changes.

If you change the method to pass a reference type by reference, that method not only can change the order in which the object is placed, but this method can also replace the object with a completely new object, and this change will be reflected back to the calling code. Basically, your friend can tell you, "From now on, use this new address, which I will read to you instead of the old one, and I will completely forget the old one."

+3


source


In C #, all parameters are passed by value by default. There are two types of types in C #, namely values โ€‹โ€‹and reference types.

A reference variable passed as a function parameter will still be passed by value; that is, if a function modifies the object referenced by this variable, after the function completes the passed variable, it will still refer to the same object (including zero) as it did before the function was called in the same context.

However, if you use a modifier ref

when declaring a function parameter than a function, the object that the variable refers to in the context of the caller can change.



For value types, this is more straight forward, but it's the same concept. Remember that int[]

is a reference type (like all arrays).

Consider the differences in these functions when passed in some array from ints:

     public static void Square1(int[] array)
     {
         for (int i = 0; i < array.Length; i++)
         {
             array[i] = array[i] * array[i];
         }
     }

     public static void Square2(int[] array)
     {
         array = {10, 20, 30};
         for (int i = 0; i < array.Length; i++)
         {
             array[i] = array[i] * array[i];
         }
     }

     public static void Square3(ref int[] array)
     {
         array = {10, 20, 30};
         for (int i = 0; i < array.Length; i++)
         {
             array[i] = array[i] * array[i];
         }
     }

      

+2


source


An array reference is passed by value automatically because it is a reference type.

Reading:

Reference types

Value types

+2


source


Most of the other answers are correct, but I find the terminology is confusing and needs to be explained. By default, you can say that all parameters in C # are passed by value, that is, the contents of the variable are copied into the method variable. It's intuitive with value type variables, but the trick is to remember that variables that are reference types (including arrays) are actually pointers. The memory location containing the pointer is copied to the method when it is passed.

When applying the ref modifier, the method gets the actual variable from the caller. For the most part, the behavior is the same, but consider the following:

public void DoesNothing(int[] nums)
{
  nums = new []{1, 2, 3, 4};
}

      

In DoNothing, we create a new int array and assign it to nums. When the method exits, the assignment is not visible to the caller because the method was manipulating a copy of the reference (pointer) that was passed.

public void DoesSomething(ref int[] nums)
{
  nums = new []{1, 2, 3, 4};
}

      

With the ref keyword, a method can essentially stretch and affect the original variable from the caller.

To achieve what you originally thought, you can create a new array and return it, or use Array.CopyTo () in the caller.

+2


source


You do not pass it by reference. Array is passed by value, but arrays in .NET are reference types, so you are passing a reference to the array, so you see squares of values.

+1


source


Arrays are objects and are passed by reference. Ints are structs and are passed by value (unless you use a keyword ref

in your method signature according to the picky guy in the comments) (who was right) (but picky).

0


source


Read the following SO question - it explains the differences between pass by value and pass by reference. The accepted answer has a link to it for a good article on the topic that should help you understand the difference.

what is the difference between passing by value and following a reference using c #

0


source







All Articles