2010-08-16 8 views
6

Entiendo que cualquier Colección (aquí estoy hablando de regular no genérico) debería haber implementado ICollection, IEnumerable e IList en caso de colección de objetos regular o IDictionary en el caso de los Diccionarios.¿Por qué implementamos las interfaces recursivamente?

[Aún así, la pregunta que no es específico de colecciones]

IList se deriva de ICollection y IEnumerable

ICollection se deriva de IEnumerable

no se trata sólo de lo suficiente como para hacer una colección (Por ejemplo, ArrayList) implementar IList?

En el navegador de objetos está mostrando que las clases de colección (por ejemplo, ArrayList) están implementando IList, ICollection e IEnumerator.

Entiendo que incluso si especificamos las tres colecciones, .Net va a aceptar las definiciones solo una vez.

Pero mi pregunta es,

  1. ¿Hay alguna buena práctica o recomendación que nos guía para especificar las tres interfaces para la clase de colección (o cualquier clase similar a esto)?

  2. ¿O es solo propiedad del Examinador de objetos que se muestra como 3 implementaciones separadas? [Acabo de comprobar y descubrí que no es propiedad del navegador Object. Examinador de objetos sólo muestra las interfaces que se especifican en la definición de clase]

+4

Las declaraciones que describes pueden ser redundantes, pero no son recursivas. – dthorpe

Respuesta

1

Creo que esto solo debe ser claro para los desarrolladores o para ayudar a reforzar la estructura de la interfaz. Lo que quiero decir es que imagine que tiene una interfaz para las clases de estructura de datos e implementa IDataObject. IDataObject luego implementa ISecurable, e ILoggable. Las clases regulares que crees podrían simplemente implementar IDataObject, pero ¿qué ocurre si el creador de IDataObject cambia la implementación más tarde y deja ILoggable? Esto puede cambiar la funcionalidad de tu código. Entonces, para evitar esto, cuando crea su clase que hereda de IDataObject, puede decir explícitamente que también quiere implementar ISecurable e ILoggable, solo para estar seguro.

No sé con certeza por qué lo hicieron con IList, pero esas dos razones son mi mejor estimación sobre por qué.

1

Con el fin de acceder a un objeto a través de una interfaz, la definición de clase para el objeto debe definir explícitamente que implementa la interfaz ...

Por ejemplo, puedo tener lo siguiente:

interface IAnimal { 
    public void Yelp(); 
} 

y la clase siguiente:

class Dog { 
    public void Yelp() { 
    // do yelping 
    } 
} 

Ahora, el perro realmente grita; Sin embargo, ya que no podrá declarar que implementa IAnimal, yo puedo no hacer lo siguiente:

IAnimal poodle = new Dog(); 
poodle.Yelp(); 

Con el fin de solucionar este problema con la definición de perro debe ser cambiado a:

class Dog : IAnimal { 
    public void Yelp() { 
    // do yelping 
    } 
} 
+0

La definición para la clase OR A BASE CLASS debe especificar que implementa la interfaz. Si Dog implementa IAnimal, y Poodle hereda de Dog, entonces un Poodle se puede convertir en un IAnimal y la función de Yelp invocada sobre él. – supercat

2

¿No es suficiente hacer una colección (Eg ArrayList) para implementar IList?

Es suficiente. La declaración de una clase:

public MyCollectionClass : IList { 
} 

que significará su MyCollectionClass implementa IList, ICollection y IEnumerable.

En el navegador de objetos está mostrando las clases de colección (P. ej.ArrayList) están implementando IList, ICollection e IEnumerator.

Este es un detalle del Examinador de objetos, o bien la clase base simplemente implementó las clases de colección especificando todas las interfaces. Sin embargo, no hay ninguna razón para hacerlo.

5

I crea es solo el navegador de objetos que lo muestra de esa manera. Acabo de probar esto:

using System.Collections; 
using System.Collections.Generic; 

public class Foo : IEnumerable<int>, IEnumerable 
{ 
    public IEnumerator<int> GetEnumerator() { return null; } 
    IEnumerator IEnumerable.GetEnumerator() { return null; } 

} 

public class Bar : IEnumerable<int> 
{ 
    public IEnumerator<int> GetEnumerator() { return null; } 
    IEnumerator IEnumerable.GetEnumerator() { return null; } 
} 

Cargando esto en el navegador de objetos mostraba ambas interfaces en ambas clases.

Tenga en cuenta que a veces hay puede ser un punto a redeclarandolos una interfaz si usted está heredando de otra aplicación - que le permite reimplementar la interfaz si previamente ha sido implementado de manera explícita o de forma no virtual. No creo que ese sea el caso aquí, pero vale la pena mencionarlo.

En general, definitivamente no tiene que especificar todas las interfaces, y generalmente no lo haría.

+0

Esto no funciona para mí en VS2010. Además, para mis clases personalizadas, el navegador de objetos omite las interfaces implícitas. – ladenedge

+0

@ladenedge: Esto también estaba en VS2010 para mí (VS2010 Pro si es relevante). Me está mostrando las interfaces en "Tipos de base". ¿Qué te está mostrando allí? –

+0

Hola, Gracias por su respuesta. Pero no es propiedad de Object Browser. Lo encontré hace algún tiempo. Si solo lo derivamos de IList, el buscador de objetos solo muestra IList. Si derivamos tanto de IList como de IEnumerable, el navegador de objetos muestra ambos. – SaravananArumugam

2

Ahora, pienso que usted está pidiendo, dado

interface IA {}; 
interface IB : IA {}; 
interface IC : IB {}; 

¿Cuál es la diferencia entre:

class MyClass : IC {}; 

y

class MyClass : IA, IB, IC {}; 

Y la respuesta es, absolutamente nada. La segunda versión lo hace un poco más claro para otros programadores, pero generará un código idéntico.

Cuestiones relacionadas