2 Stimmen

C# Aufruf einer Methode und Variablenumfang

Warum werden die Karten unten geändert? Habe mich verwirrt.. verstehen, die Übergabe von ref, die ok funktioniert.. aber wenn ein Array übergeben ist nicht tun, wie ich erwarte. Kompilieren unter .NET3.5SP1

Vielen Dank!

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

5voto

JaredPar Punkte 699699

Arrays sind Referenztypen, was kurz gesagt bedeutet, dass der Wert des Arrays nicht direkt in einer Variablen enthalten ist. Stattdessen verweist die Variable auf den Wert. Der folgende Code wird dies hoffentlich etwas besser erklären ( List<T> ist auch ein Referenztyp).

List<int> first = new List<int>()( new int[] {1,2,3});
List<int> second = first;
first.Clear();
Console.WriteLine(second.Count);  // Prints 0

In diesem Szenario gibt es eine List<int> die in der ersten Zeile erstellt wird und auf die sich die Variable first bezieht. In der zweiten Zeile wird keine neue Liste erstellt, sondern eine zweite Variable mit dem Namen second, die sich auf die gleiche List<int> Objekt als erstes. Diese Logik gilt für alle Referenztypen.

Wenn Sie die variablen Karten an die Methode übergeben, übergeben Sie nicht eine Kopie des vollständigen Arrays, sondern eine Kopie der variablen Karten. Diese Kopie bezieht sich auf das gleiche Array-Objekt wie die ursprünglichen Karten. Daher sind alle Änderungen, die Sie an dem Array vornehmen, durch den ursprünglichen Verweis sichtbar.

4voto

rein Punkte 31987

Eine Variable vom Typ Referenz hat enthält ihre Daten nicht direkt; sie enthält eine Referenz auf ihre Daten. Wenn Sie einen Parameter vom Referenztyp durch Wert übergeben, ist es möglich, die Daten, auf die der Verweis zeigt, zu ändern, beispielsweise wie der Wert eines Klassenmitglieds. Sie können jedoch nicht den Wert des Verweises selbst nicht ändern; das heißt, Sie können kann nicht dieselbe Referenz verwenden, um Speicher für eine neue Klasse zuzuweisen und die außerhalb des Blocks bestehen bleibt. Um dies zu tun, übergeben Sie den Parameter mit dem ref oder out Schlüsselwort.

http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

2voto

Guffa Punkte 663241

Wenn Sie einen Referenztyp (wie ein Array) als Wert an eine Methode übergeben, übergeben Sie eine Kopie der Referenz. Es ist immer noch das gleiche Objekt, auf das verwiesen wird, es wird keine Kopie des Arrays selbst erstellt.

2voto

Christian Hayter Punkte 29931

Bei der Übergabe von Parametern an Methoden gibt es drei verschiedene Konzepte, die zu beachten sind:

  • By Value vs. By Reference Parameter
  • Wert- vs. Referenztypen
  • Veränderliche vs. unveränderliche Typen

In Ihrem Beispiel ist das String-Array ein Referenztyp, ist ein veränderlicher Typ und wird nach Wert übergeben. Der Compiler wird Sie den Inhalt des Arrays immer ändern lassen, da er veränderbar ist. Da es sich jedoch um einen Referenztyp handelt, verweisen der aufrufende Code und der aufgerufene Code auf denselben Array-Inhalt, so dass der aufrufende Code die Änderungen "sieht". Die Tatsache, dass es als Wert übergeben wird in diesem Fall ist irrelevant, da die Array-Variable des aufgerufenen Codes zwar eine Kopie der Variablen des aufrufenden Codes erhalten hat, aber beide auf dieselbe Stelle im Speicher zeigen.

2voto

Jon Skeet Punkte 1325502

Wie bereits in anderen Antworten gesagt wurde, liegt es daran, dass ein Referenz wird weitergereicht nach Wert .

Ich habe eine Artikel über Argumentübergabe in C# die Sie vielleicht zusätzlich zu den Antworten hier nützlich finden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X