usando tipos tipo ser referencia objeto genericos generico debe datos crear generics f# extension-methods type-constraints generic-type-argument

generics - ser - tipos de datos genericos en java



Métodos de extensión para tipos genéricos específicos (4)

Bueno, puedes usar restricciones, pero no con tipos sellados como int.

type IEnumerable<''a when ''a :> InheritableType> = member this.Blah = this.ToString()

Hmm ...

Estoy intentando crear varios métodos de extensión para un tipo genérico vinculado a parámetros genéricos específicos en F #, pero el lenguaje no parece permitirme:

Lo que quiero hacer es algo como lo siguiente:

type IEnumerable<int> with member this.foo = this.ToString()

Sin embargo, me da el error de compilación (subrayando la palabra clave int ):

Identificador inesperado en el nombre del tipo. Operador de infijo esperado, símbolo de cotización u otro token.

Lo siguiente funciona, aunque no vincula específicamente el parámetro de tipo genérico a int , como deseo:

type IEnumerable<''a> with member this.foo = this.ToString()

¿Hay alguna forma de lograr este objetivo en F #? ¿Acaso estoy usando la sintaxis incorrecta? De lo contrario, agradecería que alguien sugiriera una solución alternativa, tal vez utilizando restricciones de tipo en alguna parte.


Los métodos genéricos de extensión ahora están disponibles en F # 3.1:

open System.Runtime.CompilerServices open System.Collections.Generic [<Extension>] type Utils () = [<Extension>] static member inline Abc(obj: IEnumerable<int>) = obj.ToString() printfn "%A" ([1..10].Abc())


Para ayudar a otros a buscar soluciones similares, aquí hay un ejemplo que muestra cómo usar métodos de extensión genéricos con restricciones de tipo. En el ejemplo siguiente, hay una restricción de tipo que requiere que el argumento de tipo pasado expone un constructor predeterminado. Esto se hace usando el atributo [<CLIMutable>] aplicado al registro de Order . Además, estoy restringiendo el resultado del método al tipo pasado.

Para usar el método de extensión, debe especificar el tipo que desea usar. Tenga en cuenta que también extiendo una interfaz de diccionario genérica.

[<Extension>] type ExtensionMethds () = [<Extension>] static member inline toObject<''T when ''T: (new: unit -> ''T)> (dic: IDictionary<string,obj>): ''T = let instance = new ''T() // todo: set properties via reflection using the dictionary passed in instance [<CLIMutable>] type Order = {id: int} let usage = let dictionaryWithDataFromDb = dict ["id","1" :> obj] let theOrder = dictionaryWithDataFromDb.toObject<Order>() theOrder


Esto no es posible en la versión actual de F #, desafortunadamente. Vea la pregunta relacionada aquí .