Frage

Ich arbeite in .NET 3.5. Ich habe eine Klasse "A", die einen Stapel und eine Gettter -Eigenschaft hat, die beim Rufen den ersten Artikel im Stapel entfernt und den nächsten abholt.

Nachdem ich die Klasse initialisiert hatte, sah ich, dass der Getter arbeitet, ohne angerufen zu werden, und entfernt das obere Element im Stapel, wodurch mir schlechte Ergebnisse erzielt werden. Ein Haltepunkt im Getter zeigte niemanden, der ihn durchläuft.

Wenn ich die Eigenschaft in eine Funktion ändere, wird der Stapel in Ordnung zurückgegeben.

Ich würde mich freuen, wenn jemand erklären könnte, warum das ist.

Hier ist die vereinfachte Klasse:

 public class A
    {
        private Stack<string> Urls;

        public A(string title, string[] array)
        {
            Urls = new Stack<string>();
            foreach (string s in array)
            {
                Urls.Push(s);
            }
        }

        public string Url
        {
            get { return Urls.Peek(); }
        }
        public string NextUrl
        {
            get{
            if (Urls.Count > 1)
                { Urls.Pop(); } 
            return Urls.Peek(); 
            };
        }            
    }
War es hilfreich?

Lösung

Erstens ist es im Allgemeinen eine schlechte Idee, einen Immobilien -Accessor zu ändern. Am meisten sollte es faul etwas initialisieren - oder möglicherweise einen volatilen Wert geben (wie DateTime.Now tut).

Zweitens sehen Sie dies wahrscheinlich, wenn Sie unter dem Debugger laufen - es greift auf Eigenschaften zu, während Sie Code durchlaufen. Das würde wahrscheinlich erklären, warum der Haltepunkt auch nicht getroffen wurde.

Andere Tipps

Urls.Pop();

will sein

return Urls.Pop();

Da gibt es den Wert zurück und Entfernt es gleichzeitig aus der Liste


Nachdem Sie Ihre Frage erneut gelesen haben, sieht es so aus, als ob der Debugger Eigenschaften bewertet. Wenn Sie die Anwendung ohne Debugger ausführen, erhalten Sie das gleiche Problem?

Das ist ein schlechtes Design, denke ich. Ein GET -Accessor sollte das Objekt nicht so mutieren, dass bei nachfolgenden Aufrufen unterschiedliche Ergebnisse führen.

IMO, das Problem hier ist eine Immobilie, die nicht offene Nebenwirkungen hat. Dies sollte eine Methode sein:

    public string GetNextUrl() { /* */ }

Ansonsten passieren überall schlechte Dinge (Debugger, Datenbindung usw.). Gehen Sie nicht davon aus, dass jemand nur einmal eine Eigenschaft liest.

Die einzig vernünftige Verwendung von Nebenwirkungen in Eigenschaften ist Dinge wie faule Lade, aufgeschobene Initialisierung usw. Es sollte immer noch den gleichen Wert melden, wenn sie nacheinander ohne andere offensichtliche Mutationsaufrufe aufgerufen werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top