为什么卡片会在下方更改?让我感到困惑..理解通过ref传递哪个工作正常..但是当传递数组时并没有像我预期的那样做。在.NET3.5SP1下编译
非常感谢
void btnCalculate_Click(object sender, EventArgs e)
{
string[] cards = new string[3];
cards[0] = "old0";
cards[1] = "old1";
cards[2] = "old2";
int betResult = 5;
int position = 5;
clsRules myRules = new clsRules();
myRules.DealHand(cards, betResult, ref position); // why is this changing cards!
for (int i = 0; i < 3; i++)
textBox1.Text += cards[i] + "\r\n"; // these are all new[i] .. not expected!
textBox1.Text += "betresult " + betResult.ToString() + "\r\n"; // this is 5 as expected
textBox1.Text += "position " + position.ToString() + "\r\n"; // this is 6 as expected
}
public class clsRules
{
public void DealHand(string[] cardsInternal, int betResultInternal, ref int position1Internal)
{
cardsInternal[0] = "new0";
cardsInternal[1] = "new1";
cardsInternal[2] = "new2";
betResultInternal = 6;
position1Internal = 6;
}
}
答案 0 :(得分:5)
数组是引用类型,简而言之,数组的值不直接包含在变量中。相反,变量指的是值。希望以下代码能够更好地解释这一点(List<T>
也是一种引用类型)。
List<int> first = new List<int>()( new int[] {1,2,3});
List<int> second = first;
first.Clear();
Console.WriteLine(second.Count); // Prints 0
在这种情况下,在第一行创建了List<int>
,首先由变量引用。第二行不创建新列表,而是创建名为second的第二个变量,该变量引用与第一个相同的List<int>
对象。此逻辑适用于所有引用类型。
当您将变量卡传递给方法时,您不会传递完整数组的副本,而是传递变量卡的副本。此副本引用与原始卡相同的阵列对象。因此,通过原始引用可以看到对数组所做的任何修改。
答案 1 :(得分:4)
引用类型的变量 不直接包含其数据;它 包含对其数据的引用。什么时候 你通过引用类型参数传递 价值,有可能改变 这样的参考指出的数据 作为类成员的价值。 但是,您无法更改该值 引用本身;那是你 不能使用相同的参考 为新类分配内存 让它坚持在街区之外。至 这样做,使用传递参数 引用或退出关键字。
http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx
答案 2 :(得分:2)
当您通过值将引用类型(如数组)传递给方法时,您将传递它的引用的副本。它仍然是引用的同一个对象,它不会创建数组本身的副本。
答案 3 :(得分:2)
将参数传递给方法时,需要注意三个不同的概念:
在您的示例中,字符串数组是Reference类型,是Mutable类型,并按值传递。编译器将始终允许您更改数组的内容,因为它是Mutable。但是,由于它是Reference类型,因此调用代码和被调用代码都指向相同的数组内容,因此调用代码“看到了更改”。它在这种情况下通过值传递的事实是无关紧要的,因为虽然调用代码的数组变量确实已经传递了调用代码变量的副本,但它们都指向内存中的相同位置。 / p>
答案 4 :(得分:2)
正如其他答案所说,这是因为引用正在按值传递 。
除了这里的答案之外,我还有一个你会发现有用的article on argument passing in C#。
答案 5 :(得分:1)
将数组作为对象传递时,不会复制它。接收方法使用相同的实例。 在某种意义上,数组总是通过ref传递。当一个数组以及任何其他引用类型的实例作为参数传递时,接收方法在同一个实例上获取它自己的引用副本类型。没有创建实际对象的副本。
如果您需要传递副本,则必须明确说明:自己创建副本或克隆数组。没有为你做的原因很明显 - 复制一个数组可能很昂贵,你不需要它,除非它真的是必要的
答案 6 :(得分:1)
数组是引用类型,因此可能会发生变化。