C#调用方法和变量范围

C#调用方法和变量范围,c#,C#,下面为什么要换卡片?使我困惑。。了解通过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

下面为什么要换卡片?使我困惑。。了解通过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;
    }
}
void btnCalculate\u单击(对象发送者,事件参数e)
{
字符串[]卡片=新字符串[3];
卡片[0]=“old0”;
卡片[1]=“old1”;
卡片[2]=“old2”;
int-betResult=5;
int位置=5;
clsRules myRules=新的clsRules();
myRules.DealHand(卡片、betResult、ref位置);//为什么要换卡片!
对于(int i=0;i<3;i++)
textBox1.Text+=cards[i]+“\r\n”;//这些都是新的[i]…不是预期的!
textBox1.Text+=“betresult”+betresult.ToString()+“\r\n”;//这是预期的5
textBox1.Text+=“position”+position.ToString()+“\r\n”;//这是预期的6
}
公共类clsRules
{
public void DealHand(字符串[]cardsInternal,int betResultInternal,ref int position1Internal)
{
cardsInternal[0]=“new0”;
cardsInternal[1]=“new1”;
cardsInternal[2]=“new2”;
betResultInternal=6;
位置1内部=6;
}
}

将数组作为对象传递时,不会复制该数组。接收方法适用于同一实例。从某种意义上说,数组总是通过ref传递。当数组以及任何其他引用类型的实例作为参数传递时,接收方法会在该类型的同一实例上获取自己的引用副本。不会创建实际对象的副本

如果需要传递副本,则必须明确说明这一点:自己创建副本或克隆阵列。不为您这样做的原因很明显——复制阵列可能会很昂贵,除非确实需要,否则您不会想要它

引用类型的变量不存在 不直接包含其数据;信息技术 包含对其数据的引用。什么时候 通过传递引用类型参数 值,则可以更改 参考文献所指的数据,如 作为类成员的值。 但是,不能更改该值 引用本身的定义;就是你, 不能使用相同的引用来引用 为新类分配内存,并 让它保持在街区外。到 为此,请使用 ref或out关键字


当您通过值向方法传递引用类型(如数组)时,您传递的是其引用的副本。它仍然是被引用的同一个对象,它不会创建数组本身的副本。

数组是引用类型,因此可能会发生更改。

数组是引用类型,简而言之,这意味着数组的值不会直接包含在变量中。相反,变量引用的是值。希望下面的代码能够更好地解释这一点(
List
也是一种参考类型)

List first=newlist()(newint[]{1,2,3});
列表第二=第一;
首先,清除();
Console.WriteLine(秒数);//打印0
在这种情况下,在第一行创建了一个
列表
,该列表首先由变量引用。第二行不创建新列表,而是创建名为second的第二个变量,该变量引用与第一行相同的
list
对象。此逻辑适用于所有引用类型


将变量卡传递到方法中时,不会传递完整数组的副本,而是传递变量卡的副本。此副本引用与原始卡相同的阵列对象。因此,对数组所做的任何修改都可以通过原始引用看到

将参数传递给方法时,需要注意三个不同的概念:

  • 按值与按参考参数
  • 值与引用类型
  • 可变类型与不可变类型

在您的示例中,字符串数组是引用类型,是可变类型,并按值传递。编译器将始终允许您更改数组的内容,因为它是可变的。但是,由于它是引用类型,调用代码和被调用代码都指向相同的数组内容,因此调用代码“看到了更改”。在本例中,它是按值传递的事实是不相关的,因为尽管被调用代码的数组变量确实被传递了调用代码变量的副本,但它们都指向内存中的相同位置。

正如其他答案所说,这是因为引用是按值传递的


除了这里的答案之外,我还有一个你可能会发现很有用的方法。

说“从某种意义上说,数组总是通过ref传递”不是一个好主意,因为这忽略了通过引用传递真正含义的更严格的概念。特别是,将其设为ref参数可以改变行为;我是斯科特,又叫戴夫。谢谢大家。我发现这篇文章很好。
List<int> first = new List<int>()( new int[] {1,2,3});
List<int> second = first;
first.Clear();
Console.WriteLine(second.Count);  // Prints 0