Por que não posso adicionar um acessor definido para uma propriedade anulado?
-
22-07-2019 - |
Pergunta
Em uma classe base que tem essa propriedade:
public virtual string Text
{
get { return text; }
}
Eu quero substituir essa e retornar um texto diferente, mas eu também gostaria de ser capaz de definir o texto, então eu fiz o seguinte:
public override string Text
{
get { return differentText; }
set { differentText = value; }
}
Este, porém, não funciona. Recebo um vermelho squiggly sob set
dizendo que eu não posso substituir porque ele não tem um acessor set. Por que isso é um problema? O que devo fazer?
Solução
Em seu segundo bloco de código que você está criando um método set público, mas a palavra "substituir" na declaração faz o olhar do compilador para um método com a mesma assinatura na classe base. Uma vez que não pode encontrar esse método não permitirá que você criar o seu conjunto.
Como ArsenMkrt diz que você pode mudar a sua declaração de base para conter um conjunto protegido. Isso permitirá que você para substituí-lo, mas desde que você ainda não será capaz de mudar a assinatura que você não pode promover este método para público em sua subclasse, de modo que o código ainda postou não vai funcionar.
Em vez disso você quer necessidade de adicionar um método set virtual público à sua classe base que não faz nada (ou mesmo lança uma exceção se você tentar e chamá-lo), mas isso vai contra o que um usuário da classe seria de esperar que o comportamento para ser por isso, se você fizer isso (e eu não recomendo) certifique-se que é tão bem documentado que o usuário não pode perder:
///<summary>
///Get the Text value of the object
///NOTE: Setting the value is not supported by this class but may be supported by child classes
///</summary>
public virtual string Text
{
get { return text; }
set { }
}
//using the class
BaseClass.Text = "Wibble";
if (BaseClass.Text == "Wibble")
{
//Won't get here (unless the default value is "Wibble")
}
Caso contrário declarar o conjunto como um método separado em sua classe filho:
public override string Text
{
get { return differentText; }
}
public void SetText(string value)
{
differentText = value;
}
Outras dicas
public virtual string Text
{
get { return text; }
protected set {}
}
propriedade mudança de classe base como esta, você está tentando substituir o método conjunto que não existe
Você quer mais recursos para ser exposto ao usar um tipo criança. Parece que você não deseja substituir, você quer sombra. Basta usar a nova palavra-chave para ocultar a propriedade de texto somente leitura sob sua propriedade legível / gravável.
Na classe base:
protected string text;
public string Text
{
get { return text; }
}
Na classe derivada:
new public string Text
{
get { return text; }
set { text = value; }
}
É um problema porque você está quebrando o encapsulamento. Você não pode substituir algo e torná-lo mais acessível, que jogaria tudo sobre encapsualtion para fora da janela.
Essa é a regra e se aplica no seu caso também, eventhough você está realmente expor algo que não é o valor original.
Não há nenhuma maneira de fazer exatamente o que você tentou. Você tem que quer fazer um setter na classe base, ou usar um método diferente de definir o novo valor.
Você pode ocultar a propriedade da classe base:
public new string Text
{
get { return differentText; }
set { differentText = value; }
}
Mas, nesse caso, que a propriedade só será utilizada quando manipular o objeto através de uma variável deste tipo, não o tipo de base