match value with
| :? list<#SomeType> as l -> l //Is it possible to match any list of a type derived from SomeType?
| _ -> failwith "doesn't match"
Corrispondenza del modello rispetto al tipo generico utilizzando il parametro di tipo "flessibile"
risposta
No, sfortunatamente non è possibile fare qualcosa del genere: il CLR non fornisce alcun modo efficiente per eseguire quel tipo di test del tipo. Vedi How to cast an object to a list of generic type in F# e F# and pattern matching on generics in a non-generic method implementing an interface per alcune (piuttosto brutte) soluzioni.
Come già sottolineato, non esiste un modo per farlo direttamente (la corrispondenza del modello può solo associare valori, ma non può associare nuove variabili di tipo). Oltre al (più generale) soluzione per KVB è possibile utilizzare il fatto che tutte le collezioni implementano non generico IEnumerable
, in modo da poter verificare la presenza di questo tipo:
match box value with
| :? System.Collections.IEnumerable as l when
// assumes that the actual type of 'l' is 'List<T>' or some other type
// with single generic type parameter (this is not fully correct, because
// it could be other type too, but we can ignore this for now)
typedefof<SomeType>.IsAssignableFrom
(value.GetType().GetGenericArguments().[0]) ->
l |> Seq.cast<SomeType>
| _ -> failwith "doesn't match"
Il codice verifica se il valore è un non-generic IEnumerable
e se il parametro type è sottotipo di SomeType
. In questo caso, abbiamo ottenuto un elenco di alcuni tipi derivati, quindi possiamo lanciarlo su una sequenza di valori SomeType
(questo è leggermente diverso rispetto a lavorare con l'elenco di valori dei tipi derivati, ma non dovrebbe essere rilevante per scopi pratici) .
Successivamente ho avuto bisogno di qualcosa di simile per l'abbinamento di istanze Lazy. Ecco la mia soluzione, nel caso qualcuno la trovi utile.
let (|Lazy|_|) (value : obj) =
if box value <> null then
let typ = value.GetType()
if typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof<Lazy<_>> then
Some(typ.GetGenericArguments().[0])
else None
else None
Usage:
match value with
| Lazy typ when typeof<SomeType>.IsAssignableFrom(typ) -> (value :?> Lazy<_>).Value
| _ -> failwith "not an instance of Lazy<#SomeType>"
Secondo il F# 2.0 specification, par. 14.5.2 (Risoluzione dei vincoli di sottotipo), non funzionerà, perché: "I tipi di F # non supportano la covarianza o la contravarianza".
non il più pulito, ma efficace:
let matchType<'T>() =
try
let o = Activator.CreateInstance<'T>()
match box o with
| :? Type1 -> printfn "Type1"
| :? Type2 -> printfn "Type2"
| _ -> failwith "unknown type"
with
| ex -> failwith "%s" (ex.ToString())
- 1. Parametro modello di corrispondenza per tipo di modello
- 2. Tipo di trasmissione utilizzando il parametro tipo
- 3. Ottieni il tipo di parametro generico
- 4. Annotazione esplicita del tipo per costruttore generico di tipo generico
- 5. Corrispondenza del modello sul tipo Classe [_]?
- 6. dinamico rispetto al tipo di oggetto
- 7. Upcasting con un parametro di tipo generico
- 8. Forza un parametro di tipo generico come tipo di classe?
- 9. Definizione del parametro del tipo generico limitato in C#
- 10. Come ottenere il parametro di tipo generico della classe base?
- 11. Il parametro di tipo generico predefinito non può essere dedotto
- 12. Tipo generico da Enum e il modello di generatore
- 13. passano tipo enum generico come parametro (java)
- 14. Ottieni il tipo effettivo di un parametro oggetto generico
- 15. Il parametro di tipo non estende il tipo dato
- 16. È possibile vincolare un parametro del tipo di metodo generico C# come "assegnabile dal parametro di tipo della classe contenente"?
- 17. Tipo di parametro funzione utilizzando decltype
- 18. C# determinare tipo generico
- 19. Tratto associato utilizzando il tipo associato del tratto come parametro
- 20. gcc-4.9.2: parametro modello non di tipo
- 21. Come posso vedere il tipo dedotto per un parametro del tipo di modello?
- 22. Recupero del tipo non chiuso di un tipo generico che chiude un tipo generico
- 23. corrispondenza di un parametro generico a un tipo associato in un impl
- 24. C++ modello non-tipo tipo di parametro deduzione
- 25. Come richiedere un tipo generico implementare un protocollo generico utilizzando un tipo specifico nel protocollo
- 26. Tipo mancata corrispondenza dopo l'estrazione di un'espressione con tipo di ritorno generico
- 27. Specifica generico tipo di raccolta parametro in fase di esecuzione
- 28. Raccoglitore modello MVC ASP.NET per tipo generico
- 29. Errore del parametro di tipo predefinito nel codice modello
- 30. Tipo di ritorno generico Java
Non che io immagino è importante, ma perché avete bisogno per abbinare con un elenco di qualche tipo? Se la lista è omogenea, puoi semplicemente elaborare la lista element by element e va bene. Se la lista è eterogenea, non si può comunque considerare l'elenco come un'unità logica. Qual è il problema che stai cercando di risolvere qui? –
Suppongo che avrei dovuto usare il mio codice attuale. Sto solo usando la lista per semplicità. La domanda è come fare una corrispondenza flessibile sui parametri del tipo. –
Daniel