C# 代码是如何实现引用传递的?
在main中,我声明了一个本地int[]数组(int[]nums)。我没有通过推荐。 但当我打印本地数组的值时,我得到每个元素的平方值。 原因是什么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
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;
}