Por coleções aulas em C # (como ArrayList) herdam múltiplas interfaces se uma dessas interfaces herda do restante?
-
06-07-2019 - |
Pergunta
Quando eu pressionar F12 na palavra-chave ArrayList para ir para metadados gerados a partir vs2008, descobri que a declaração de classe gerada da seguinte forma
public class ArrayList : IList, ICollection, IEnumerable, ICloneable
Eu sei que o IList já herda de ICollection e IEnumerable, então por que ArrayList redundante herdar essas interfaces?
Solução
OK, eu fiz alguma pesquisa. Se você criar a seguinte hierarquia:
public interface One
{
void DoIt();
}
public interface Two : One
{
void DoItMore();
}
public class Magic : Two
{
public void DoItMore()
{
throw new NotImplementedException();
}
public void DoIt()
{
throw new NotImplementedException();
}
}
E compilá-lo, em seguida, fazer referência a DLL em uma solução diferente, digite Magia e Imprensa F12, você receberá o seguinte:
public class Magic : Two, One
{
public Magic();
public void DoIt();
public void DoItMore();
}
Você vai ver que a hierarquia interface é achatada, ou o compilador está adicionando as interfaces em? Se você usar o refletor você obter os mesmos resultados também.
Update: Se você abrir a DLL em ILDASM, você vai vê-lo dizendo:
implementos ... Dois
implementos ... Um.
Outras dicas
As interfaces extras são mostrados porque eles estão implícitos por IList. Se você implementar IList, você também deve implementar ICollection e IEnumerable.
Eu estou apenas supondo, mas acho que na realidade ele só implementa IList no código, mas os shows documentação do resto das interfaces, bem como para torná-lo explícito para o programador usando a classe.
A partir MSDN ....
Se uma classe implementa duas interfaces que contêm um membro com a mesma assinatura, em seguida, implementar esse membro na classe fará com que ambos interfaces para usar esse membro como seu implementação.
implementação explícita também é usado a casos resolvem onde duas interfaces cada declarar diferentes membros da mesmo nome, como uma propriedade e um método:
Não aceite isso como resposta.
Eu estou repetindo o que workmad3 disse acima.
Ao implementar isso no ArrayList, torna-se fácil para um saber - quais interfaces ArrayList implementos, sim, que vai até IList para descobrir que ele implementa ICollection & IEnumerable
.Isso evita a necessidade de ir para trás e para frente na cadeia de herança.
EDIT: No nível básico, uma interface implementar outra interface não pode fornecer a implementação. A classe de derivados (de IList) implementa, portanto, indirectamente ICollection & IEnumerable bem. Assim, mesmo se você escrever sua própria classe que implementa IList (e não adicionar ICollection, IEnumerable na declaração.) - você vai ver que ele terá que fornecer a implementação para ICollection & IEnumerable
raciocínioE das workmad3 faz sentido.
Meu palpite seria que o CLR não suporta uma interface que herda de outra interface.
C # no entanto suporta esta construção, mas tem que 'achatar' a árvore de herança para ser compatível CLR.
[Edit]
Depois de tomar conselhos de seguir rapidamente configurar um projeto VB.Net:
Public Interface IOne
Sub DoIt()
End Interface
Public Interface ITwo
Inherits IOne
Sub DoIt2()
End Interface
Public Class Class1
Implements ITwo
Public Sub DoIt() Implements IOne.DoIt
Throw New NotImplementedException()
End Sub
Public Sub DoIt2() Implements ITwo.DoIt2
Throw New NotImplementedException()
End Sub
End Class
Compilar resultados na seguinte (C #):
public class Class1 : ITwo
{
public Class1();
public void DoIt();
public void DoIt2();
}
Este show que VB.Net faz não achatar a hierarquia de interface ao invés de C #. Eu não tenho idéia de por que isso seria.