Inscreva-se agora

* Você receberá as últimas notícias e atualizações sobre suas celebridades favoritas!

Postagens em alta

Blog

Ocultação de Nomes em C#: Entendendo Escopos e Herança
Aprenda C#

Ocultação de Nomes em C#: Entendendo Escopos e Herança 

No C#, a ocultação de nomes ocorre quando um nome declarado em um escopo interno oculta um nome com o mesmo identificador em um escopo externo. Isso pode acontecer em vários cenários, como ao aninhar namespaces, classes e blocos de código, ou ao herdar membros de uma classe base. Neste artigo, exploraremos os dois tipos principais de ocultação de nomes: através de aninhamento e através de herança.

Ocultação de Nomes Através de Aninhamento

A ocultação de nomes através de aninhamento ocorre quando uma entidade em um escopo interno usa o mesmo nome que uma entidade em um escopo externo. Nesse caso, o nome externo é ocultado no escopo interno. Vamos ver um exemplo:

class A
{
    int i = 0; // Variável de instância

    void F()
    {
        int i = 1; // Oculta a variável de instância 'i'
        void M1()
        {
            float i = 1.0f; // Oculta a variável 'i' do método F
            Func<double, double> dobrar = (double i) => i * 2.0; // Oculta a variável 'i' de M1
        }
    }

    void G()
    {
        i = 1; // Refere-se à variável de instância 'i'
    }
}

Neste exemplo:

  • Dentro do método F, a variável i local oculta a variável de instância i.
  • Dentro da função local M1, a variável i oculta a variável local i do método F.
  • Dentro da expressão lambda, o parâmetro i oculta a variável i de M1.

Essa ocultação ocorre porque o C# permite que variáveis locais redefinam variáveis de escopos superiores.

Ocultação de Nomes em Sobrecarga de Métodos

Quando um nome em um escopo interno oculta um nome em um escopo externo, isso afeta todos os métodos sobrecarregados com o mesmo nome. Isso significa que todas as sobrecargas externas ficam inacessíveis no escopo interno.

class Outer
{
    static void F(int i) {}
    static void F(string s) {}

    class Inner
    {
        static void F(long l) {}

        void G()
        {
            F(1); // Invoca Inner.F (long)
            F("Olá"); // Erro: Não há correspondência em Inner
        }
    }
}

Aqui, a declaração de F(long) em Inner oculta todas as sobrecargas de F em Outer. Isso causa um erro ao tentar invocar F(string).

Ocultação de Nomes Através de Herança

Na herança, a ocultação de nomes ocorre quando uma classe derivada declara membros com o mesmo nome que membros herdados da classe base. Isso pode ocultar constantes, campos, propriedades, eventos, métodos e indexadores herdados.

class Base
{
    public void F() {}
}

class Derived : Base
{
    public void F() {} // Aviso: oculta o método F da classe base
}

No exemplo acima, o método F em Derived oculta o método F herdado de Base. Isso gera um aviso no compilador, pois a ocultação de nomes herdados não é um erro, mas pode indicar um comportamento inesperado.

Usando o Modificador new

Para eliminar o aviso e indicar explicitamente que a ocultação de um membro herdado é intencional, você pode usar o modificador new:

class Base
{
    public void F() {}
}

class Derived : Base
{
    public new void F() {} // Oculta explicitamente F da classe base
}

O modificador new informa ao compilador que a ocultação do membro é proposital.

Limitações da Ocultação

A ocultação de nomes herdados é restrita ao escopo da classe que introduz o novo nome. Se o membro oculto for declarado como private, ele não será acessível em classes derivadas adicionais.

class Base
{
    public static void F() {}
}

class Derived : Base
{
    private new static void F() {} // Oculta F apenas em Derived
}

class MoreDerived : Derived
{
    static void G()
    {
        F(); // Invoca Base.F, pois F de Derived é privado
    }
}

Neste exemplo, o método F em Derived oculta F de Base, mas como F é privado em Derived, a classe MoreDerived não pode acessar essa versão e, portanto, invoca Base.F.

Conclusão

A ocultação de nomes em C# é um mecanismo que ocorre tanto por aninhamento quanto por herança. Entender como e quando ocorre a ocultação de nomes é essencial para evitar conflitos de nomes inesperados e garantir que seu código funcione como esperado. Usar o modificador new pode ajudar a deixar as intenções claras ao lidar com a ocultação através da herança.

Posts relacionados

Deixe um comentário


Campos obrigatórios são marcado com *