C# - Violando o Liskov Substitution Principle (LSP)
![]() |
Vamos recordar um dos princípios SOLID, o princípio da substituição de Liskov ou LSP. |
O princípio da substituição de Liskov (LSP) , um dos princípios SOLID, declara que uma classe base deve poder ser substituída por sua classe derivada sem alteração no comportamento final.
Assim, pelo princípio LSP, a instância de uma classe base deve possibilitar sua substituição por instâncias das classes derivadas sem que se necessita qualquer alteração no código.
Esse princípio permite verificar se você esta implementando a herança de forma correta.
Se ocorrer a violação do princípio significa que a herança foi implementada de forma incorreta. Para isso ocorrer basta uma classe derivada sobrescrever um método herdado da classe base e assim mudar o comportamento esperado.
Para perceber isso vamos criar uma classe chamada MinhaCollection com uma propriedade Count pública e uma classe MeuArray que herda de MinhaCollection:
class MinhaCollection
{
public int Count { get ; set ; }
}
class MeuArray : MinhaCollection
{
}
|
Podemos então fazer o seguinte:
class Program
{
static void Main()
{
MinhaColecao colecao = new MeuArray();
}
}
|
Embora o Count em MeuArray seja imutável visto que arrays possuem um tamanho definido e um número fixo de elementos, isso ainda esta correto.
Até agora tudo ok.
Vamos agora permitir que a classe MinhaColecao adicione novos elementos e a seguir vamos sobrescrever este método na classe MeuArray fazendo outra implementação:
class MinhaCollection
{
public int Count { get ; set ; }
public virtual void AddItem(item item)
{
Console.WriteLine("Incluir Item");
}
}
class MeuArray : MinhaCollection
{
public override void AddItem(item item)
{
throw new System.NotSupportedException();
}
}
|
Acabamos de violar o Princípio da Substituição de Liskov.
Embora o código seja compilado, como podemos converter o MeuArray em MinhaCollection, também podemos adicionar um novo item a um Array de tamanho fixo e isso está incorreto. Mudamos o comportamento.
Então, aqui está um problema que surge ao violar o Princípio de Substituição de Liskov. Nesses casos, temos que lançar uma exceção de tempo de execução.
Na verdade a classe Array da plataforma .NET também viola o LSP visto que ela deriva de ICollection<T>.
Nota: De acordo com a documentação do MSDN, o System.Array implementa o ICollection, mas o System.Array não fornece uma propriedade Count (mas você sempre pode usar o método de extensão Count()).
class Program
{
static void Main()
{
ICollection<int> collection = new int[] {0};
collection.Add(1); // <-- Throws NotSupportedException
}
}
|
O método
Add não está visível como membro da matriz, pois é
implementado explicitamente. Mas sempre somos capazes de converter uma matriz em
ICollection<T> e operar em sua instância a partir do nível da interface
subjacente.
E estamos conversados.
"Ninguém jamais
viu a Deus; se nos amamos uns aos outros, Deus está em nós, e em nós é perfeito
o seu amor.
Nisto conhecemos que estamos nele, e ele em nós, pois que nos deu do seu
Espírito.
E vimos, e testificamos que o Pai enviou seu Filho para Salvador do mundo."
1 João 4:12-14
Referências:
C# - StreamReader, StringReader e TextReader . Qual a ... - Macoratti
C# - Imprimindo um arquivo texto - Macoratti
C# - Usando OpenFileDialog - Macoratti
C# - Formatando arquivos textos - Macoratti