2016-05-10 16 views
6

Jestem nieco niejasny na temat składni dziedziczenia dla interfejsów w C#.Deklarowanie dziedziczenia interfejsu w C#

Na przykład:

public interface IFoo 
{ 
} 
public interface IBar : IFoo 
{ 
} 

Jaka jest różnica między tym:

public interface IQux : IBar 
{ 
} 

a to:

public interface IQux : IBar, IFoo 
{ 
} 

Albo, dla prawdziwego przykład światowej Dlaczego ICollection<T> uznanej tak:

public interface ICollection<T> : IEnumerable<T>, IEnumerable 

zamiast tego:

public interface ICollection<T> : IEnumerable<T> 

skoro IEnumerable<T> już dziedziczy IEnumerable?

+0

To dobre pytanie –

+1

Nie jest konieczne jawne wymienianie podstawowych interfejsów jako zaimplementowane, ale jest to dobre dla przejrzystości. IOW, nie ma różnicy funkcjonalnej. – Blorgbeard

+0

uzgodnione z @Blorgbeard, nie ma różnicy, po prostu dobre dla jasności –

Odpowiedz

5

Eric Lippert wyjaśnia to bardzo dobrze w tym artykule:

https://blogs.msdn.microsoft.com/ericlippert/2011/04/04/so-many-interfaces

Jeśli IBar dziedziczy z IFoo więc, z punktu widzenia kompilatora, nie ma różnicy pomiędzy:

public interface IQux : IBar 
{ 
} 

a to:

public interface IQux : IBar, IFoo 
{ 
} 

Możesz stwierdzić, że IQux zawiera IFoo jeśli uważasz, że to sprawia, że ​​kod jest bardziej czytelny. Lub możesz wybrać nie.

2

Generics nie istniał od samego początku - spojrzeć na C# 1.0 docs i nie będzie widać IEnumerable<T>.

Jeśli chodzi o pierwsze pytanie: nie ma różnicy (nawet z jawnych implementacji interfejsu miarę Mogę powiedzieć).

rozważaniach to:

public interface IFoo 
{ 
    void M(); 
} 

public interface IBar : IFoo { } 
public interface IQux : IBar, IFoo { } 
public interface IQux2 : IBar { } 

// Both work: 
// class X : IQux 
class X : IQux2 
{ 
    void IFoo.M() { } 
} 
+0

^^ Co powiedział. Chociaż wydaje mi się, że czasami sprowadza się to do sposobu, w jaki chcesz używać swoich interfejsów. Możesz wymusić na klasie, która implementuje IBar, implementację IFoo. A może jest coś o IFoo, które nie ma sensu dla IBar. Myślę, że to naprawdę sprowadza się do tego, czego * TY * potrzebujesz od swoich interfejsów i * W JAKI SPOSÓB * planujesz ich użyć lub w jaki sposób odnoszą się do siebie nawzajem. –

1

Stosowna cytat z C# Specification (wersja 5), ​​sekcja 13.4:

klasy lub struct, które bezpośrednio implementuje interfejs również bezpośrednio realizuje wszystkich interfejsów bazowych interfejsu użytkownika w sposób dorozumiany. Jest to prawdą, nawet jeśli klasa lub struktura nie jawnie wymienia wszystkie interfejsy podstawowe na liście klasy podstawowej.

Nie ma potrzeby jawnego wymieniania interfejsów bazowych. Zakładam, że jest to zrobione dla jasności dla programisty.

+0

@xandercoded W jaki sposób jest dobry dla polimorfizmu? – DavidG

+0

@xandercoded powinieneś przywrócić jedną z twoich odpowiedzi i edytować, aby wyjaśnić, co masz na myśli. Sekcja komentarzy niepowiązanej odpowiedzi nie jest tym miejscem. – Blorgbeard

+0

I nadal wydaje się, że brakuje ci punktu: nie jest konieczne * deklarowanie *, że 'ICollection' dziedziczy po' IEnumerable', ponieważ dziedziczy po 'IEnumerable ', który i tak dziedziczy po 'IEnumerable'. Zatem niezależnie od tego, czy je zadeklarujesz, czy nie, dziedziczy po 'IEnumerable'. Pytanie nie dotyczyło tego, dlaczego powinno to robić, chodziło o wymaganą składnię. – Blorgbeard