Implementar membros explícitos da interface em uma classe

Concluído

Em C#, a implementação de interface explícita permite que uma classe implemente membros da interface de uma forma que eles só sejam acessíveis através da interface, não da instância da classe. Isso é útil quando uma classe implementa várias interfaces com membros que têm a mesma assinatura.

Várias interfaces em uma classe

Uma classe em C# pode implementar várias interfaces, permitindo herdar o comportamento de várias fontes. A capacidade de combinar várias interfaces é crucial porque o C# não suporta herança múltipla de classes. A implementação de várias interfaces permite que uma classe tenha recursos diferentes e garante que ela siga as regras definidas por essas interfaces.

  • As interfaces definem um grupo de funcionalidades relacionadas.
  • Uma classe ou struct deve implementar todos os membros das interfaces que herda.
  • As interfaces podem conter métodos, propriedades, eventos e indexadores.

Aqui estão duas interfaces simples para o nosso exemplo:

public interface IEnglishDimensions
{
    float Length();
    float Width();
}

public interface IMetricDimensions
{
    float Length();
    float Width();
}

Membros explícitos da interface

Em C#, uma classe pode herdar de apenas uma classe, mas pode implementar várias interfaces. Isso é especialmente importante quando várias interfaces têm os mesmos nomes de membros. Para evitar confusão, usamos a implementação de interface explícita.

A implementação explícita da interface garante que cada membro de uma interface tenha uma implementação única, evitando conflitos. Ele também esclarece a qual interface um membro pertence quando uma classe implementa duas ou mais interfaces com os mesmos nomes de membro. A implementação de interface explícita permite que uma classe cumpra os requisitos de múltiplas interfaces, fornecendo diversas funcionalidades.

Para implementar explicitamente um membro de uma interface, adicione o nome da interface e um ponto antes do nome do membro. Aqui está um exemplo:

public class Box : IEnglishDimensions, IMetricDimensions
{
    float IEnglishDimensions.Length()
    {
        return 30.0f;
    }

    float IEnglishDimensions.Width()
    {
        return 20.0f;
    }

    float IMetricDimensions.Length()
    {
        return 76.2f;
    }

    float IMetricDimensions.Width()
    {
        return 50.8f;
    }
}

Neste código, a Box classe está implementando duas interfaces: IEnglishDimensions e IMetricDimensions. Ambas as interfaces têm membros nomeados Length e Width. Para evitar confusão, cada membro está explicitamente ligado à sua interface.

Observação

Os membros da interface explicitamente implementados não têm modificadores de acesso como public, private, etc. Eles só podem ser acessados através de uma instância da interface, não da classe. Isso significa que não podes chamar Box.Length(), mas podes chamar IEnglishDimensions.Length() se tiveres uma instância de Box que esteja a ser tratada como um IEnglishDimensions.

Usar membros explícitos da interface

Você precisa criar instâncias das interfaces e chamar seus membros para executar e testar o código que utiliza membros explícitos da interface. Isso garante que a implementação correta seja invocada com base no tipo de interface.

Box box = new Box();
IEnglishDimensions eDimensions = box;
IMetricDimensions mDimensions = box;

Console.WriteLine($"Length in inches: {eDimensions.Length()}");
Console.WriteLine($"Width in inches: {eDimensions.Width()}");
Console.WriteLine($"Length in centimeters: {mDimensions.Length()}");
Console.WriteLine($"Width in centimeters: {mDimensions.Width()}");

Neste exemplo, a instância da classe Box é convertida tanto para IEnglishDimensions como IMetricDimensions para aceder aos membros explícitos da interface. A saída exibe as dimensões em inglês e unidades métricas.

Length in inches: 30
Width in inches: 20
Length in centimeters: 76.2
Width in centimeters: 50.8

Em C#, você pode implementar várias interfaces em uma classe, usando a implementação de interface explícita para resolver conflitos de nomenclatura quando os membros têm as mesmas assinaturas. Os membros explicitamente implementados são acessados através da instância da interface, não da instância da classe, garantindo a funcionalidade adequada e evitando ambiguidade. Essa abordagem melhora a capacidade de manutenção do código, definindo claramente o comportamento pretendido para cada interface, tornando a base de código mais fácil de entender e ampliar.