答えて
二つの新しい "特別な" 演算子は、このF#のリリースであり、かつ(?)(< - ?)。これらは定義されていませんが、オーバーロードが可能であるため、自分で定義することができます。特別なビットは、第2オペランドをどのように扱うかです。有効なF#識別子である必要がありますが、演算子を文字列として実装する関数に渡す必要があります。言い換えれば:
a?b
に脱糖さ:
(?) a "b"
と:これらの演算子の非常に単純な定義は
(?<-) a "b" c
できます
a?b <- c
がに脱糖されます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)
gettorの戻り値の型がジェネリックであることから、あなたはつまり、ほとんどの場合、使用場所でそれを指定する必要がありますことをご注意:
let name = foo?Name : string
それでもチェーン・コール(ことができますが? )ジェネリックもある)(の最初の引数(以降?):
:let len = foo?Name?Length : int
もう一つ、もっと面白い、実装は、VBで提供するために再利用CallByNameの方法があります
ことの利点は、DLRを使用して動的なオペレータを実装nuget上など
"?"演算子は動的言語ランタイム(DLR)に関係します。つまり、コンパイル時ではなく、実行時にオブジェクトメンバ(メソッド、プロパティ)にバインドするときに使用します。
これはC#でも動的メンバー呼び出しがどのように機能するのかと期待して面白かったです。悲しいかな、C#はこの機能を「擬似」タイプ(「ダイナミック」IIRC)で公開しています。私の意見では、これはコードが幾分明確でないことを示しています(呼び出しが早期バインドか遅いバインドかを知るために変数宣言を追跡する必要があるためです)。
正確な構文はわかりませんが、推測しなければならないのであれば、 "。" (ドット)演算子。以下のように:
let x = foo?Bar()
または多分:
let x = foo.?Bar()
"コールが早期バインドか遅いバインドかを知るために変数宣言を追跡する必要があるため" ...非常に遠くまで追跡する必要はありません。 dynamicはローカル変数でなければならず、型メンバーにはなれません。変数が動的であるかどうかを調べるために非常に遠くにスクロールする必要がある場合は、リファクタリングする必要があります。さらに、変数の名前の上にマウスを置くと、IDEが喜んでタイプを伝えます。 – Randolpho
良い点。それが価値あるものであれば、「遅延型呼び出し」演算子を「動的」型実装よりも好む別の理由があります。インタフェースを実装することによってDLRにフックすることができるとすれば、同じ参照に対して早期呼び出しと遅い呼び出しをしたいと考えています。 –
fooの型になるべき好奇心から、なぜfoo.Bar()の代わりにそのようにしたいのですか? さらに、リフレクションで同じ結果を得ることはできませんか? – em70
モジュールFSharp.Interop.Dynamicがあり、IDispatchのCOMオブジェクトを操作、正しく両方のプロパティとフィールドを処理するということです。
let ex1 = ExpandoObject() in
ex1?Test<-"Hi";
ex1?Test |> should equal "Hi";
それはオープンソースですが、Apacheライセンス、あなたはimplementationを見ることができ、それはユニットテストexample casesが含まれています。
- 1. F#リストとシーケンス演算子
- 2. F#のHaskellリスト差分演算子
- 3. F#(.. ..)演算子の使用/オーバーロード
- 4. 演算子if演算子
- 5. F番号:String.Joinと| F#では>演算子
- 6. C++:演算子オーバーロード、演算子+
- 7. C++演算子+演算子+ =オーバーロード
- 8. Xval演算子と比較演算子?
- 9. のF# - 型int演算子をサポートしていません..-
- 10. 変換F#のパイプライン演算子(<|, >>、<<)OCamlの
- 11. タイプキャスト演算子
- 12. Groovy ==演算子
- 13. ストリンジェライザ演算子#
- 14. ! &&演算子Java
- 15. ドット演算子
- 16. groovy ^演算子
- 17. ハスケル:=演算子?
- 18. Java + =演算子?
- 19. 演算子オーバーロード==
- 20. Bigint +演算子
- 21. "?"演算子
- 22. Groovy *。演算子
- 23. モジュロ演算子
- 24. * =演算子は
- 25. オーバーロードテンプレート演算子*
- 26. ルビーパイプ演算子
- 27. ポストインクリメント演算子++
- 28. 。 &演算子
- 29. C#の演算子の演算順序
- 30. オーバーロード算術演算子
メモとして、F#PowerPackには妥当なデフォルト実装が含まれているようです。 –