1

私はF#の初心者です。

BaseとDerivedの2つのクラスがあります。

Baseにはいくつかの方法があります。Derivedは、いくつかのメソッドをそのまま継承し、いくつかはオーバーライドします。派生クラスも新しいメソッドを導入しました。

私はオブジェクトのセットを持っています、いくつかはベースであり、いくつかは派生です。

タプルの2つの要素のリストがあり、タプルの2番目の要素はポリモーフィック階層のメソッドです。

入力を読み取り、入力ごとにリストを調べて、各タプルの最初の要素(述語)を入力に適用するプログラムについて考えてみましょう。

述語がtrueの場合、ベースまたは派生の可能性があるオブジェクトでタプルの2番目の要素を呼び出します(タプルの最初の要素の値によって異なります)。

現在の2つのリスト(1つはBase用、もう1つはDerived用)ではなく、このようなタプルの1つのリストがあれば便利です。これは可能ですか?

基本クラスがmethod1とmethod2を定義すると仮定します。

Derivedクラスがmethod2とmethod4を定義(オーバーライド)するとします。

let predList = 
  [(predicate1, Base.method1);
  (predicate2, method2);
  (predicate4; Derived.method4) 
  ... 
]

 while ... do
     let input = ReadInput
     if IsBase(input)
         then 
             let method = List.Find matchingPredicate predList
             let baseObj = ChooseBaseObject(input)
             baseObj.method  // ????
         else 
             let method = List.Find matchingPredicate predList
             let derivedObj = ChooseDerivedObject(input)
             derivedObj.method  // ????

このようなコードでは、predicate2を満たす特定の入力が、IsBase(input)が返す内容に応じて、Derived.method2またはBase.method2への呼び出しをトリガーする場合があります。

4

1 に答える 1

1

method最も簡単な方法は、 をスタンドアロン関数のグループにラップすることです。

let wrap_method1 (x :Base) = x.method1()
let wrap_method2 (x :Base) =
   match x with
   | :? Derived as xd -> xd.method2()
   | _ -> x.method2()
let wrap_method4 (x :Base) =
   match x with
   | :? Derived as xd -> xd.method4()
   | _ -> ()

// use
let predList = 
    [(predicate1, wrap_method1);
    (predicate2, wrap_method2);
    ... ]

while ... do
    let input = ReadInput
    let method = List.Find matchingPredicate predList
    method input
于 2012-09-30T05:01:30.533 に答える