C# 代码是如何实现引用传递的?

C# 代码是如何实现引用传递的?,c#,delegates,C#,Delegates,在main中,我声明了一个本地int[]数组(int[]nums)。我没有通过推荐。 但当我打印本地数组的值时,我得到每个元素的平方值。 原因是什么 delegate void tsquare(int[] a); static void Main() { int[] nums = { 1, 2, 3 }; tsquare sqr = new tsquare(SomeClass.Square); sqr(nums); foreach (int intva

在main中,我声明了一个本地int[]数组(int[]nums)。我没有通过推荐。 但当我打印本地数组的值时,我得到每个元素的平方值。 原因是什么

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];
         }
     }

   }
委托无效方(int[]a);
静态void Main()
{
int[]nums={1,2,3};
tsquare sqr=新的tsquare(SomeClass.Square);
sqr(nums);
foreach(整数整数单位为nums)
{
控制台写入线(intvals);
}
}
上课
{
公共静态空方块(int[]数组)
{
for(int i=0;i
更新:

我认为int[]{Array}是一种值类型,委托完成了 一些技巧。现在从你的回答中,我知道数组是引用类型。

在C#中,所有参数默认按值传递。C#中有两种类型,即值类型和引用类型

引用类型的变量作为参数传递给函数时,仍将按值传递;也就是说,如果函数更改了该变量引用的对象,则在函数完成后,传入的变量仍将引用相同的对象(包括null),就像在相同上下文中调用函数之前一样

但是,如果在声明函数参数时使用
ref
修饰符,则函数可能会更改调用者上下文中变量引用的对象

对于值类型,这更简单,但概念相同。请记住,
int[]
是一种引用类型(与所有数组一样)

当传入一些int数组时,请考虑这些函数的差异:

     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];
         }
     }
publicstaticvoidsquare1(int[]数组)
{
for(int i=0;i
您不是通过引用传递它。数组是按值传入的,但是.NET中的数组是引用类型,因此您传入了对数组的引用,这就是为什么您看到值是平方的。

数组是对象,并且是按引用传入的。int是结构,按值传递(除非按照注释中挑剔的家伙在方法签名中使用
ref
关键字)(谁是对的)(但很挑剔)。

阅读以下SO问题-它解释了按值传递和按引用传递之间的区别。被接受的答案中有一个链接,链接到一篇关于这个主题的好文章,这将帮助你理解其中的区别


数组引用自动按值传递,因为它是引用类型

阅读:


其他大多数答案都是正确的,但我认为这个术语令人困惑,值得解释。默认情况下,可以说C#中的所有参数都是按值传递的,这意味着变量的内容被复制到方法变量中。这对于值类型的变量是很直观的,但诀窍在于记住引用类型的变量(包括数组)实际上是指针。指针包含的内存位置在传入时复制到方法

public void DoesSomething(ref int[] nums)
{
  nums = new []{1, 2, 3, 4};
}
应用ref修饰符时,该方法从调用方获取实际变量。在大多数情况下,行为是相同的,但考虑如下:

public void DoesNothing(int[] nums)
{
  nums = new []{1, 2, 3, 4};
}
在DoesNothing中,我们实例化一个新的int数组并将其分配给nums。当方法退出时,调用方看不到分配,因为该方法正在操作传入的引用(指针)的副本

public void DoesSomething(ref int[] nums)
{
  nums = new []{1, 2, 3, 4};
}
使用ref关键字,该方法基本上可以从调用者那里获得并影响原始变量本身


为了达到您最初想要的效果,您可以创建一个新数组并返回它,或者在调用者中使用array.CopyTo()

  • 引用类型与值类型
  • 通过值传递与通过引用传递
  • 让我们先解决第二个问题

    通过值传递某个内容意味着您为该方法提供了该值的自己的副本,并且该方法可以随意更改该值,而不会将这些更改泄漏回调用该方法的代码中

    例如:

    Int32 x = 10;
    SomeMethod(x); // pass by value
    
    在本例中,调用返回后,x不可能是10以外的任何值,因为SomeMethod对其值副本所做的任何操作都只对其自身的值所做

    然而,通过引用传递意味着我们并没有真正给方法它自己的值,而是给它我们自己的值所在的内存位置,因此该方法对值所做的任何事情都会反映回代码中,因为实际上,只有一个值在起作用

    因此:

    Int32 x = 10;
    SomeMethod(ref x); // pass by reference
    
    在这种情况下,x在SomeMethod返回后可能会持有与调用前不同的值

    这就是通过值传递和通过引用传递

    现在我们来搅乱这片水域。还有另一个概念,引用类型和值类型,很多人对此感到困惑。你的问题暗示你也对这个问题感到困惑,如果你没有,我很抱歉

    引用类型实际上是由两部分组成的。这是一个引用,它是引用所指的任何东西。想一想你知道地址的房子。你把地址写在一张纸上实际上并没有把整个房子都写在上面
    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
    
    public void Test(SomeType t)
    {
        t.Value = 25;
    }