Pergunta

Acabei de ler as informações sobre esta página, e enquanto um novo? O operador é mencionado, não está claro para mim o que seria seu uso.
Alguém poderia fornecer uma explicação rápida, postar um código cortado de como esse operador seria usado e possivelmente mencionar um caso de uso?
Editar: Isso é realmente estranho, eu notei que o? O operador não é mais mencionado nas notas de lançamento de Don. Alguma idéia de por que isso?

Foi útil?

Solução

Existem dois novos operadores "especiais" nesta versão F#, (?) E (? <-). Eles não são definidos, mas estão disponíveis para sobrecarga, para que você possa defini -los você mesmo. O bit especial é como eles tratam seu segundo operando: eles exigem que ele seja um identificador F# válido, mas passa para a função implementando o operador como uma string. Em outras palavras:

a?b

é dessugarado para:

(?) a "b"

e:

a?b <- c

é dessugarado para:

 (?<-) a "b" c

Uma definição muito simples desses operadores pode ser:

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)

Observe que, como o tipo de retorno para o gettor é genérico, você terá que especificá -lo no site de uso na maioria dos casos, ou seja:

let name = foo?Name : string

Embora você ainda possa fazer a corrente (?) (Como o primeiro argumento de (?) Também é genérico):

let len = foo?Name?Length : int

Outra implementação mais interessante é reutilizar o método callbyname fornecido pelo 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

A vantagem disso é que ele lidará com as propriedades e os campos corretamente, trabalhará com os objetos de Idispatch com, etc.

Outras dicas

Parece o "?" O operador está relacionado ao dinâmico Runtime Runtime (DLR). Ou seja, você o usa quando deseja vincular a um membro do objeto (método, propriedade) em tempo de execução, e não no momento da compilação.

É engraçado porque eu esperava que isso fosse como a invocação dinâmica de membros funcionaria em C# também. Infelizmente, C# expõe essa funcionalidade por meio de um tipo "pseudo" ("dinâmico" iirc). Na minha opinião, isso deixa o código um pouco menos claro (porque você precisa rastrear a declaração variável para saber se a chamada é no início ou no final do limite).

Não conheço a sintaxe exata, mas se eu tivesse que adivinhar, ela substitui ou aumenta o "". Operador (DOT). Como em:

let x = foo?Bar()

ou talvez:

let x = foo.?Bar()

There is a module FSharp.Interop.Dynamic, on nuget that implements the dynamic operator using the dlr.

let ex1 = ExpandoObject() in
ex1?Test<-"Hi";
ex1?Test |> should equal "Hi";

It's open source, Apache license, you can look at the implementation and it includes unit test example cases.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top