A propriedade getter é executada sem ninguém ligar
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();
};
}
}
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.