¿Por qué ICollection no contiene un método Add? [cerrado]

Como en el título, ¿alguien sabe por qué el ICollection interfaz no contiene un método Add? Parece muy extraño que la versión genérica, ICollection<T>tiene un Add pero ICollection no es. Cualquier persona con un conocimiento más profundo sobre esto sería realmente útil.

En cuanto a por qué me importa, desafortunadamente los desarrolladores que crean SharePoint nunca han aprendido acerca de los genéricos, por lo que cada colección en la API es una colección no genérica basada en ICollection. Me gustaría adjuntar varios métodos de extensión a ICollection que implican añadir a la colección, entre otras cosas, pero esto parece imposible (al menos no posible sin reflexión).

EDIT:

Bastantes personas son especulando la razón es porque ICollection.Add requeriría un Object, y por lo tanto no sería seguro para tipos. Este no es el caso. IList tiene an Add método que toma un Object. Simplemente necesita hacer una verificación de tipo y una conversión en un método que tome Object.

El argumento que implementa una matriz ICollection y por lo tanto no puede tener un Add tampoco retiene agua. Si ICollection tuvo un Add método, solo necesitaría implementarse explícitamente en las matrices y lanzar una excepción (como lo hacen muchos de los métodos que las matrices implementan actualmente).

Realmente esperaba que alguien tuviera una referencia a una explicación de uno de los diseñadores.

preguntado el 27 de julio de 12 a las 15:07

@MicahArmantrout, dice ICollection<T> lo hace, pero ICollection no es. -

@MicahArmantrout Te vinculaste a la versión genérica. Ya dijo que la versión genérica lo tiene. Él está preguntando por qué el uno no genérico no lo hace. -

Tal vez sea porque un Add in ICollection tendría que tomar object, pero no tiene sentido definir Add(object) en, por ejemplo List<int>. (no puede agregar ningún objeto a un List<int>) Sin embargo, IList tiene Add(object), por lo que este argumento no se sostiene demasiado bien. Las razones son probablemente históricas: así se hizo por primera vez, y nunca se consideró que valiera la pena hacer ese cambio radical. -

La respuesta es simple... los diseñadores eran unos incompetentes. No tiene sentido lógico que Add and Remove esté en IList pero no en ICollection, y los comentarios que intentan racionalizarlo son ridículos (aunque no tan ridículos como el antiintelectualismo grosero y ofensivo de las relaciones públicas). Es una suerte que hayan aprendido un poco con las clases genéricas, pero la ICollection fallida significa que no puede escribir código generalizado que opere en no listas, como HashSet. y Diccionario . -

8 Respuestas

Me parece que la denominación de las interfaces confunde las expectativas. ICollection y ICollection<T> ni siquiera están en la misma cadena de herencia: la mayoría de las colecciones simplemente implementan ambos.

La documentación establece lo que hace la interfaz, así que tomando esto solo, uno no esperaría Add existir:

Define el tamaño, los enumeradores y los métodos de sincronización para todas las colecciones no genéricas.

¿Que pienso? Personalmente, creo que es una metedura de pata directa o la segunda vez (al presentar las interfaces genéricas) los diseñadores eligieron poner Add in ICollection<T> porque esta vez era más común necesitarlo.

La opción IList tiene Add y hereda ICollection mientras que el IList<T> no tiene Add y hereda ICollection<T>, tal como Add.

Atribuyalo a la evolución/maduración del diseño de la jerarquía de tipos.


En cuanto a los métodos de extensión, puedes hacer algo como:

public static void AnotherMethod<T>(this ICollection<T> collection, T item) { }

Y utilícelo así:

ICollection<string> s;
s.AnotherMethod("");

Respondido el 21 de Septiembre de 15 a las 15:09

ICollection<sting> ... Me gusta, quizás podamos tener referencias musicales más decentes ;) - Moo-Jugo

ICollection puede ser cualquier cosa. Podría ser algo que no es más que enumerable. No hay razón allí debemos frijol Add método, o de hecho un Remove. Si observa la interfaz más de cerca, es prácticamente de solo lectura. Puede ver cuántos elementos hay y puede enumerarlos. Eso es todo. Esto tiene mucho sentido, de una manera abstracta.

Cuando llegamos a ICollection<T>, ahora estamos siendo muy específicos. Sabemos exactamente qué tipo de objeto contiene y por lo tanto podemos:

  • Añadir nuevos elementos de <T>.
  • Búscalos usando un IEquitable tipo de interfaz.
  • Eliminarlos, utilizando la misma metodología.

En esencia, la diferencia es que ICollection<T> es algo concreto.

Respondido 27 Jul 12, 15:07

Puedo estar de acuerdo con tu opinión, pero creo que la razón subyacente tiene más que ver con la evolución del diseño. IList toma agregar aunque no sepa qué tipo está en la lista, todas las listas no genéricas tienen este problema. La segunda vez con todas las nuevas interfaces para genéricos, los diseñadores pueden tener la oportunidad de unificar mejor las interfaces base. O eso o es solo un error de nombre directo. - adam houldsworth

Según Hermanos Albahari

Las versiones genéricas y no genéricas difieren mucho más de lo que cabría esperar, especialmente en el caso de ICollection.

Las razones de esto son principalmente históricas:porque los genéricos llegaron después,las interfaces genéricas fueron desarrolladas con el beneficio de comprensión retrospectiva.

Por esta razón,

ICollection<T>no se extiende ICollection,

IList<T> no se extiende IList,

y IDictionary<TKey, TValue> no se extiende IDictionary.

Para resumir ICollection<T> ha evolucionado al no cometer los errores que se cometieron en ICollection.Esta es la razón por ICollection<T> tiene un método Add y ICollection no..

Respondido 27 Jul 12, 16:07

De MSDN

No necesita agregar tipos de colección a tipos conocidos cuando se usa polimórficamente en lugar de otras colecciones o interfaces de colección. Por ejemplo, si declara un miembro de datos de tipo IEnumerable y lo usa para enviar una instancia de ArrayList, no necesita agregar ArrayList a los tipos conocidos.

Cuando usa colecciones polimórficamente en lugar de tipos que no son de colección, deben agregarse a los tipos conocidos. Por ejemplo, si declara un miembro de datos de tipo Object y lo usa para enviar una instancia de ArrayList, agregue ArrayList a los tipos conocidos.

Respondido 27 Jul 12, 15:07

Basado en definicion msdn, Es

Define el tamaño, los enumeradores y los métodos de sincronización para todas las colecciones no genéricas

Eso significa que la ICollection representa una corriente o con una secuencia de datos que vas a leer. Como diría eso probablemente la decisión que está detrás de la SharePoint API es proporcionar flujo genérico de datos usted lee desde el servidor.

Respondido 27 Jul 12, 15:07

Una conjetura es que si ICollection tenía el Add método, ¿qué se necesitaría? Object por supuesto. Este fue un gran problema con ninguna matriz genérica, que antes de C # 2.0 tenía.

El problema sería que puede agregar diferentes tipos a la misma colección

Respondido 27 Jul 12, 15:07

Esto realmente no sería un problema. Solo tendría que hacer una verificación de tipo en el método ICollection.Add(object) que arroja si es del tipo incorrecto. - MgSam

@MgSam correcto, pero aún se siente mal tener un método que tome un objeto y luego arroje una excepción. - MBen

MgSam: Pero, ¿cómo define cuál es el tipo correcto si no es genérico? Y las excepciones de tiempo de ejecución para cosas como esta no me parecen divertidas. Por otra parte, tratar de adivinar a los desarrolladores tampoco parece divertido... - Chris

@MBen ArrayList toma object por lo que este argumento por sí solo no es suficiente para descartar por qué ICollection no lo tiene, hubo una vez un mundo antes de los genéricos. - adam houldsworth

@AdamHouldsworth ah, está bien, buen punto. Acabo de comprobar que ICollection fue antes del mundo de los genéricos. - MBen

Suposición salvaje: la interfaz ICollection es una interfaz base para otras interfaces que la amplían, como IList e IDictionary. Esas interfaces tienen diferentes implementaciones del método add. IList toma un parámetro, IDictionary necesita dos obviamente. Con los genéricos, las firmas del método de interfaz derivado no son realmente diferentes porque toman un parámetro: un tipo.

Respondido 27 Jul 12, 15:07

IColección no extiende ICollection! - Anirudha

Nunca dije que sí. Estaba hablando de la interfaz System.Collections.ICollection, que se creó antes de los genéricos. - Ian Stallings

Cuándo ICollection fue creado no había interfaces genéricas. Esto significaba que si hubiera un Add método en ICollection tendría que tener la firma Add(object). ICollection está destinado a declarar una interfaz consistente a través de colecciones de cualquier tipo, lo que obligaría a cada colección a actuar, parcialmente, como una colección de objects.

Esto se ha solucionado en ICollection<T> que tiene un metodo Add(T).

Respondido 27 Jul 12, 15:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.