Ho appena letto le informazioni su this page e mentre una nuova? operatore è menzionato, non mi è chiaro quale sarebbe il suo utilizzo.
Qualcuno potrebbe fornire una spiegazione rapida, pubblicare un codice tagliato di come sarebbe utilizzato questo operatore e possibilmente menzionare un caso d'uso?
Modifica: questo è davvero imbarazzante, ho notato che il? l'operatore non è più menzionato nelle note di rilascio di Don. Qualche idea del perché è così?Operatore F # "?"
risposta
Ci sono due nuovi operatori "speciali" in questo # versione F, e (<? -) (?). Non sono definiti, ma sono disponibili per il sovraccarico, quindi è possibile definirli da soli. Il bit speciale è il modo in cui trattano il loro 2 ° operando: richiedono che sia un identificatore F # valido, ma lo passano per funzionare implementando l'operatore come una stringa. In altre parole:
a?b
è Dezuccherato a:
(?) a "b"
e:
a?b <- c
è Dezuccherato a:
(?<-) a "b" c
Una definizione molto semplice di tali operatori potrebbero be:
let inline (?) (obj: 'a) (propName: string) : 'b =
let propInfo = typeof<'a>.GetProperty(propName)
propInfo.GetValue(obj, null) :?> 'b
let inline (?<-) (obj: 'a) (propName: string) (value: 'b) =
let propInfo = typeof<'a>.GetProperty(propName)
propInfo.SetValue(obj, value, null)
Nota che, poiché il tipo di ritorno per la gettor è generico, si dovrà specificare che ad un uso sito in maggior parte dei casi, vale a dire:
let name = foo?Name : string
anche se è ancora a catena-call (?) (dal primo argomento (?) è anche generico):
let len = foo?Name?Length : int
altro, più interessante, l'attuazione è riutilizzare il metodo CallByName fornito da VB:
open Microsoft.VisualBasic
let inline (?) (obj: 'a) (propName: string) : 'b =
Interaction.CallByName(obj, propName, CallType.Get, null) :?> 'b //'
let inline (?<-) (obj: 'a) (propName: string) (value: 'b) =
Interaction.CallByName(obj, propName, CallType.Set, [| (value :> obj) |])
|> ignore
Il vantaggio di questo è che tratterà sia le proprietà ei campi correttamente, lavorare con gli oggetti IDispatch COM, ecc
Sembra il "?" l'operatore si riferisce al Dynamic Language Runtime (DLR). Cioè, lo si usa quando si desidera associare a un membro dell'oggetto (metodo, proprietà) in fase di esecuzione piuttosto che in fase di compilazione.
È divertente perché speravo che questo sarebbe stato anche il modo in cui l'invocazione dinamica dei membri funzionava anche in C#. Purtroppo, C# espone questa funzionalità tramite un tipo "pseudo" (IIRC "dinamico"). A mio parere, questo rende il codice un po 'meno chiaro (perché devi rintracciare la dichiarazione della variabile per sapere se la chiamata è vincolata in anticipo o in ritardo).
Non conosco la sintassi esatta, ma se dovessi indovinare, sostituisce o aumenta "." operatore (punto). Come in:
let x = foo?Bar()
o forse:
let x = foo.?Bar()
"perché devi rintracciare la dichiarazione della variabile per sapere se la chiamata è vincolata in anticipo o in ritardo" ... Non è necessario tracciare molto lontano. dynamic deve essere una variabile locale e non può essere un membro di tipo; se devi scorrere molto lontano per scoprire se una variabile è o meno dinamica, è probabile che tu abbia bisogno di un refactoring. Inoltre l'IDE ti dirà volentieri il tipo se passi il mouse sopra il nome di una variabile ... – Randolpho
Buoni punti. Per quello che vale, c'è un'altra ragione per cui preferirei un operatore di "chiamata tardiva" rispetto all'implementazione di tipo "dinamico": Dato che è possibile collegare il DLR implementando un'interfaccia, posso immaginare uno scenario in cui ti piacerebbe fare le chiamate precoci e le chiamate in ritardo sullo stesso riferimento. –
Per curiosità quale dovrebbe essere il tipo di foo e perché dovrei farlo al posto di foo.Bar()? Inoltre, non riesco già a ottenere lo stesso risultato tramite la riflessione? – em70
C'è un modulo FSharp.Interop.Dynamic, su NuGet che implementa l'operatore dinamico utilizzando il dlr.
let ex1 = ExpandoObject() in
ex1?Test<-"Hi";
ex1?Test |> should equal "Hi";
è open source, licenza Apache, si può guardare la implementation e comprende test di unità example cases.
- 1. Operatore dell'applicazione di funzione ($) in F #?
- 2. Si può definire un operatore (***) in F #?
- 3. F #: parametri di tipo esplicite in operatore vincolante
- 4. Resa F #! operatore - Implementazione ed eventuali equivalenti C#
- 5. F # passando un operatore con gli argomenti a una funzione
- 6. Perché il compilatore F # fallisce con questo operatore infisso?
- 7. F # se non condizione
- 8. Copia costruttore o = operatore?
- 9. F # (.. ..) utilizzo/sovraccarico dell'operatore
- 10. parametro python operatore
- 11. F # ciclo continuo in F #
- 12. Prolog: disuguaglianza operatore
- 13. F # strano problema printfn
- 14. Risultato operatore ternario Javascript
- 15. Come dividere F [A \/B] in (F [A], F [B])
- 16. Esiste un equivalente per la creazione di un operatore implicito C# in F #?
- 17. F #: L'operatore '&' non dovrebbe normalmente essere ridefinito
- 18. sovraccarico dereference operatore
- 19. Nullptr in operatore ternario
- 20. F # interattivo vs. # soluzione F e WCF
- 21. F # - Mantieni F # interattiva dall'output di postazione
- 22. Fortran: differenza tra estensione F e F
- 23. F # tipo vincoli sulle enumerazioni
- 24. Come riscrivere Swift ++ operatore in:? Ternario operatore
- 25. Differenza tra "nuovo operatore" e "operatore nuovo"?
- 26. operatore python, nessun operatore per "non in"
- 27. Come posso creare un operatore in Haskell?
- 28. "ultimo" operatore per le funzioni?
- 29. pattern matching con le mappe in F #
- 30. Permessi F #
Come nota a margine, apparentemente, F # PowerPack include un'implementazione predefinita ragionevole. –