2

パイプライン中置演算子を使用して、返されたオブジェクトのメソッドを呼び出すことは可能ですか?

たとえば、メソッド(Method1)を持つ.Netクラス(Class1)があります。私は現在、次のようにコーディングできます。

let myclass = new Class1()
let val = myclass.Method1()

私はそれをそのようにコーディングすることもできることを知っています

let val = new Class1().Method1()

しかし、私はそれをパイプライン化できるようにしたいと思います(私は何をすべきかわからないところで以下の?を使用しています):

new Class1()
|> ?.Method1()

さらに、オブジェクトを返すメソッドがあり、そのメソッドがnullを返さなかった場合にのみそれを参照したいとします(そうでない場合はbail?)

new Class1()
|> ?.Method1()
|> ?? ?.Method2()

または、わかりやすくするために、C#コードを次に示します。

    public void foo()
    {
        var myclass = new Class1();
        Class2 class2 = myclass.Method1();
        if (class2 == null)
        {
            return;
        }
        class2.Method2();
    }
4

2 に答える 2

3

演算子に似たものを(??)かなり簡単に定義できます(ただし、演​​算子は疑問符で始めることはできません)。

let (~??) f x =
  if (x <> null) then
    f x

残念ながら、パイプライン化されたコードはもう少し冗長にする必要があります(また、newコンストラクターを呼び出すためのキーワードを削除できることに注意してください)。

Class1()
|> fun x -> x.Method1()

すべてを一緒に入れて:

Class1()
|> fun x -> x.Method1()
|> ~?? (fun x -> x.Method2())
于 2009-09-17T19:09:24.900 に答える
2

'kvb'が示唆するようにカスタム演算子を使用することは、間違いなくオプションです。nullこの場合に興味深いと思われるもう1つのアプローチは、指定したすべてのポイントで値のチェックを自動的に実行する独自の「計算式」を定義することです。これを使用するコードは次のようになります。

open System.Windows.Forms

// this function returns (0) null, or (1) btn whose parent is 
// null or (2) button whose parent is not null
let test = function
  | 1 -> new Button(Text = "Button")
  | 2 -> new Button(Text = "Button", Parent = new Button(Text = "Parent"))
  | _ -> null

let res =  
  safe { let! btn = test(2) // specify number here for testing
         // if btn = null, this part of the computation will not execute
         // and the computation expression immediately returns null
         printfn "Text = %s" btn.Text
         let! parent = btn.Parent // safe access to parent
         printfn "Parent = %s" parent.Text // will never be null!
         return parent }

ご覧のとおり、「null」になる可能性のある値を使用する場合はlet!、計算式の内部で使用します。計算式はnull、値がである場合はすぐに戻り、nullそうでない場合は残りの計算を実行するように定義できます。コードは次のとおりです。

type SafeNullBuilder() =
  member x.Return(v) = v
  member x.Bind(v, f) = 
    if v = null then null else f(v)

let safe = new SafeNullBuilder()    

ところで:これについてもっと知りたい場合は、Haskellの「Maybe」モナド(またはF#オプションタイプで動作する計算)と非常によく似ています。

于 2009-09-20T00:24:06.110 に答える