TransWikia.com

Pra que serve o sealed em C#?

Stack Overflow em Português Asked on November 27, 2021

Vi uma classe em C# que estava declarada assim, numa resposta que li no SOen:

public sealed class Link
{
     // Resto do código
}

Para que serve a palavra chave sealed no caso acima?

5 Answers

Bem, em resumo o sealed é para indicar que a classe não poderá ser herdada por outras. É o mesmo que o final do Java.

Muitos dizem que deveria ser o padrão, já que herança quase nunca é a solução. Herança traz uma bagagem muito forte e um fardo para a manutenção já que qualquer alteração nesta classe potencialmente afetará o funcionamento de todas as derivadas.

Uma estrutura de dados como uma classe é útil, mas a herança nem tanto. Claro, tem seus usos. Organizar tudo junto no objeto é muito mais vantajoso e ajuda muito mais que permitir o reuso direto. Na maioria dos casos que a pessoa quer fazer uma herança deveria fazer uma composição.

Uma struct é implicitamente sealed, e deveriam ter padronizado isso na classe. Deveria ter uma palavra opcional como open, inheritable, ou até um virtual pra usar algo já existente, ou algo semelhante a isso, o que importa é a ideia. A diferença fundamental de uma classe é que ela é sempre por referência, e, salvo otimização, tem o local de armazenamento no heap (alguns hoje admitem que poderia ser melhor nem isso ser padrão e o programador ter que dizer onde vai, mas é uma corrente pequena para o C#).

Classes seladas são simples e confiáveis, precisam de menos testes e podem evoluir melhor. Claro, se forem bem feitas. Classes abertas para herança são problemáticas até quando tudo é feito direito. Fica pior quando quando a classe pode ser herdada e instanciada. Há quem considere que classes abertas à herança sempre deveriam ser abstratas, o que eu concordo cada vez mais. Muitos problemas de OOP não existiriam assim. Mas admito também que tem caso que pode ser útil ter ambos, feito com muito cuidado.

Então use sealed por padrão até que tenha certeza que precisa da herança. E aí desenhe a classe para a herança, o que é absurdamente mais difícil.

No C# a ideia da herança padrão foi copiada do Java e foi uma ideia ruim. Já existia antes, mas fazia mais sentido em outras linguagens. Java, pela sua filosofia, errou e C# foi na onda.

Em métodos

Esse atributo também é usado em métodos, de forma bem mais rara. Nesse caso você está proibindo um método ser sobreposto quando originalmente ele era virtual, e portando polimórfico. Só faz sentido usá-lo em métodos que são herdados virtualmente e que deseja impedir que ele continue virtual a partir dali. Então ele só faz sentido existir em uma classe já herdada e em um método que na ascendente foi marcado como virtual. Métodos não explicitamente virtual podem ser considerados sealed implicitamente.

Novamente considero um erro. Se pretende que continue sendo virtual deveria ter que dizer isso. Embora nesse caso tem lá suas desvantagens. Prefiro o implícito por coerência, mas ser explícito tem seu mérito.

O nome é esquisito, mas era o que tinha. Ele seria um nonvirtual.

Answered by Maniero on November 27, 2021

sealed, quando usado em uma declaração de classe, impede que outras classes herdem dela.

public class TesteA { //... }
public sealed class TesteB : TesteA { //... }

Neste caso acima, TesteB herda de TesteA, mas uma tentativa de herdar de TesteB causará um erro de compilação.

A palavra chave sealed também pode ser usada em métodos ou propriedades:

public class TesteA { 
    protected virtual void Hello() { Console.WriteLine("TesteA cumprimenta você!"); }
}
public class TesteB : TesteA { 
    sealed protected override void Hello() { Console.WriteLine("TesteB cumprimenta você!"); }
}

Aqui vai disparar erro de compilação CS0239, não é possível sobreescrever um membro declarado como sealed

public class TesteC : TesteB { 
    protected override void Hello() { Console.WriteLine("TesteC cumprimenta você!"); }
}

Answered by Artur Trapp on November 27, 2021

É um modificador que, em classes, define que outras classes não possam herdar da especificada.

public class A { }
public sealed class B : A { } // Funciona normal. B herda de A e não pode ser herdada.
public class C : B { }        // Erro de compilação.

Este modificador também pode ser usado em membros de classes que possam ser herdadas. Isso faz com que a classe filha possa usar o comportamento definido na classe pai, mas que não possa alterá-lo.

class A
{
    protected virtual void Metodo1() => Console.WriteLine("Classe A -> 1");
    protected virtual void Metodo2() => Console.WriteLine("Classe A -> 2");
}

class B : A
{
    protected sealed override void Metodo1() => Console.WriteLine("Classe B -> 1");
    protected override void Metodo2() => Console.WriteLine("Classe B -> 2");
}

class C : B
{         
    protected override void Metodo1() => Console.WriteLine("Classe C -> 1");     
    // (^) Erro de compilação.
    protected override void Metodo2() => Console.WriteLine("Classe C -> 2");
}

Answered by Jéf Bueno on November 27, 2021

É um modificador que impede que outras classes herdam dessa classe. Esse modificador pode também ser utilizado em propriedades ou métodos.

Um exemplo básico que exemplifique isso:

class B {}
sealed class A: B {}

essa herança funciona onde A herda de B, mas, se for ao contrário isso não funciona pela restrição do modificador.

Referencia: sealed (Referência de C#)

Answered by novic on November 27, 2021

No caso de classes, o modificador sealed serve para indicar que ela não pode ser herdada.

class A {}      
sealed class B : A {}

Ou seja, B pode herdar de A, mas se eu criar uma classe C e tentar herdar de B, causará um erro de compilação.

// Causa erro
class C : B {}

A mesma coisa acontece com overriding de métodos. Se você tentar sobreescrever um método com o modificador sealed, também causará um erro de compilação.

No seu exemplo, o modificador indica que nenhuma outra classe poderá herdar da classe Link

Answered by Raul Medeiros on November 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP