Pergunta

Estou trabalhando no .NET 3.5. Eu tenho uma classe "A" que tem uma pilha e uma propriedade Getter que, quando chamada, remove o primeiro item na pilha e recupera o próximo.

Depois de inicializar a aula, vi que o getter funciona sem ser chamado e remove o item superior da pilha, dando -me maus resultados. Um ponto de interrupção no getter não mostrou ninguém passando por ele.

Quando altero a propriedade para uma função, a pilha é retornada OK.

Eu ficaria feliz se alguém pudesse explicar por que é isso.

Aqui está a classe simplificada:

 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(); 
            };
        }            
    }
Foi útil?

Solução

Em primeiro lugar, fazer com que um acessador de propriedade mude o estado geralmente é uma má idéia. O máximo que deve fazer é inicializar preguiçosamente algo - ou possivelmente dar um valor volátil (como DateTime.Now faz).

Em segundo lugar, você provavelmente está vendo isso se estiver executando o depurador - ele acessa propriedades enquanto você está passando pelo código. Isso provavelmente explicaria por que o ponto de interrupção também não estava sendo atingido.

Outras dicas

Urls.Pop();

quer ser

return Urls.Pop();

ao retornar o valor e remove -o da lista ao mesmo tempo


Na verdade, tendo releido sua pergunta, parece que é porque o depurador avalia as propriedades. Se você executar o aplicativo sem o depurador, terá o mesmo problema?

Isso é um design ruim, eu acho. Um acessador GET não deve muta o objeto de uma maneira que causa resultados diferentes nas chamadas subsequentes.

IMO, o problema aqui é ter uma propriedade com efeitos colaterais não óbvios; Este deve ser um método:

    public string GetNextUrl() { /* */ }

Caso contrário, coisas ruins acontecem em todos os lugares (o depurador, a ligação de dados, etc.). Não assuma que alguém só lê uma propriedade uma vez.

O único uso sensível de efeitos colaterais nas propriedades são coisas como carregamento preguiçoso, inicialização adiada, etc. Ele ainda deve relatar o mesmo valor quando chamado sequencialmente sem outras chamadas óbvias de mutação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top