Domanda

sto lavorando in .net 3.5. Ho una classe "A", che ha una pila e una proprietà getter, che, quando viene chiamato, rimuove il primo elemento della pila e recupera quello successivo.

Dopo l'inizializzazione della classe, ho visto che il getter funziona senza essere stato chiamato, e rimuove l'elemento in cima alla pila, dando così mi cattivi risultati. Un punto di interruzione nella getter non ha mostrato nessuno che lo attraversa.

Quando cambio la proprietà a una funzione, lo stack viene restituito ok.

Sarei felice se qualcuno potrebbe spiegare il motivo per cui è così.

Questa è la classe semplificata:

 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(); 
            };
        }            
    }
È stato utile?

Soluzione

In primo luogo, fare una funzione di accesso di proprietà modificare lo stato è generalmente una cattiva idea. La maggior parte si dovrebbe fare è pigramente inizializzare qualcosa -. O, eventualmente, dare un valore volatile (come DateTime.Now fa)

In secondo luogo, probabilmente stai vedendo questo se si sta eseguendo nel debugger - si accede a proprietà, mentre si sta passando attraverso il codice. Che probabilmente spiega perché il punto di interruzione non veniva colpito, anche.

Altri suggerimenti

Urls.Pop();

vuole essere

return Urls.Pop();

in quanto restituisce il valore di e rimuove dall'elenco, allo stesso tempo


In realtà dopo aver ri-letto la tua domanda, sembra che è perché il debugger valuta le proprietà. Se si esegue l'applicazione senza il debugger si ottiene lo stesso problema?

Questa è una cattiva progettazione credo. Un accesso get non dovrebbe mutare l'oggetto in un modo che provoca risultati diversi per le chiamate successive.

IMO, il problema qui è avere una proprietà che ha non evidenti effetti collaterali; questo dovrebbe essere un metodo:

    public string GetNextUrl() { /* */ }

In caso contrario, le cose brutte accadono ovunque (il debugger, data-binding, ecc). Non date per scontato che qualcuno legge solo una proprietà di una volta.

L'unico uso ragionevole di effetti collaterali nelle proprietà è cose come lazy-loading, inizializzazione differita, ecc Deve comunque segnalare lo stesso valore quando chiamato in sequenza senza altre chiamate mutanti evidenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top