2010-04-01 14 views
8

.NET Framework está agregando una interfaz ISet<T> con la versión 4.0. En el mismo lanzamiento, F # se está agregando como un lenguaje de primera clase. F # proporciona una clase inmutable Set<'T>.¿Por qué el conjunto F # no implementa el dispositivo SET <T>?

Me parece lógico que el conjunto inmutable proporcionado implemente la interfaz ISet<T>, pero no es así. ¿Alguien sabe por qué?

Supongo que no querían implementar una interfaz destinada a ser mutable, pero no creo que esta explicación se mantenga. Después de todo, su clase Map<'Key, 'Value> implementa IDictionary, que es mutable. Y hay ejemplos en otras partes en el marco de clases que implementan interfaces que son solo parcialmente apropiadas.

Mi otro pensamiento es que ISet<T> es nuevo, por lo que tal vez no lo consiguieron. Pero eso parece un poco delgado.

¿El hecho de que ISet<T> es genérico (v. IDictionary, que no) tiene algo que ver con eso?

Se agradecerá cualquier idea al respecto.

+0

En el propio marco .NET, 'ReadOnlyCollection ' implementa 'ICollection ', que es una interfaz mutable. – Steven

+0

@Steven A la derecha, ese es un ejemplo de una clase de infraestructura que implementa una interfaz que no es totalmente apropiada. –

Respuesta

5

A primera vista no creo que tenía conocimiento de ISet. (De hecho, eché un vistazo al correo electrónico anterior y encontré una mención de los planes de BCL para él, del 2008, pero eso fue todo. Por eso creo que no estaba en nuestro radar)

Dicho esto, F # se esfuerza para que sea compatible con la fuente entre sus bits .NET 2.0 y .NET 4.0, al punto de back-porting de entidades .NET 4.0 en FSharp.Core.dll versión 2.0. Por ejemplo, The 2.0 FSharp.Core contiene System.Tuple, System.BigInteger, System.Threading.CancelationTokenSource (parte del modelo de programación asíncrono), etc., y ISet podría ser otro trabajo para back-port (no está claro si sería 'necesario'). 'para portarlo, sin embargo).

Voy a presentar un problema para echar un vistazo, aunque puede ser discutible en este momento.

+1

Eso tiene sentido. No me di cuenta de que había un impulso para mantener F # fuente compatible en todos los marcos. Solo curiosidad, pero ¿cuál es el razonamiento detrás de esto? ¿La postura oficial es que .NET 4.0 no contiene una versión "nueva" de F #, sino más bien un paquete oficial de primera clase de F # tal como existe hoy en día? –

5

Dado que nadie más está saltando, agregaré mi especulación. En primer lugar, la mayoría de la interfaz IDictionary<'k,'v> todavía tiene sentido para un diccionario inmutable; en realidad solo agrega o elimina elementos individuales que no funcionarán. En segundo lugar, hay una cantidad decente de código que ya se ha escrito que se basa en IDictionary, por lo que poder usar valores F # con ese código es una buena ventaja.

Por otro lado, varios de los métodos de ISet<'t> requieren mutación, que incluye no solo la adición de elementos individuales, sino también varios operadores de mutación configurada, como la unión y la intersección. Además, muchos casos de uso establecidos ya están incluidos en la interfaz IEnumerable<'t>. Creo que será relativamente raro que las personas confíen en las implementaciones ISet<'t> para el código basado en conjuntos inmutables.

No creo que la genericidad tenga algo que ver con eso. Tenga en cuenta que a pesar de la documentación de MSDN, los mapas F # implementan la interfaz genérica IDictionary, no la no genérica.

+1

Esto suena plausible. Aún así, es frustrante si es cierto.Me parece un error incluir todos los métodos de interfaz que implican la mutabilidad de la clase implementadora. (Del mismo modo, creo que sería un error incluir métodos que impliquen que la clase debe ser _immutable_.) Sería bueno si 'ISet ' incluyera solo miembros de "lectura". Creo que la interfaz tal como está es demasiado obstinada, y ahora todavía no tengo una forma de comunicar simplemente que "esta es una colección de artículos únicos". (Al menos en lo que se refiere a la interoperabilidad F #) –

+0

Parece que no es la mayoría: por mi cuenta, solo cinco de los 11 miembros propios de 'ISet ' requieren una mutación. Si incluye miembros heredados de 'ICollection ', se convierte en ocho de 18. (Y de estos, al menos 'void Add (T item)' probablemente se implementará explícitamente) –

+0

Estaba pensando en escribir una respuesta similar, pero luego miré a la interfaz 'ISet ' y descubrí que tiene bastantes operaciones que todavía se pueden implementar (concretamente 'SetEquals',' IsSubsetOf', 'IsSupersetOf',' Overlaps', 'IsProperSubsetOf',' IsProperSupersetOf'), tal vez es menos que 'IDictionary', pero aún bastantes ... Otro razonamiento puede ser que no hay métodos .NET que tomarían' ISet ', por lo que no hay una razón impulsada por la aplicación para implementarlo (I Supongo que puede haber un buen caso de uso para 'IDictionary'). –

Cuestiones relacionadas