オブジェクトのプロパティ

オブジェクトのプロパティについていろいろやってみた。
"get"や"set"や"Item"が言語仕様として気持ち悪いなあ。
もう少しスマートにならんものか。


というわけでまたテケトーコード

// F#のバージョン: 1.9.2.9

type InterfaceTest = interface
   abstract Test1 : unit -> int with get,set
   abstract Test2 : unit -> int with get
   abstract Test3 : unit -> int with set
   abstract Test4 : unit -> int with set,get
   // 以下の行は "'get','set' or 'get,set' required." と表示される。
   // つまり、メソッド定義の with の後にはgetとsetしか書けないらしい。
   // "get"と"set"だけ特別扱いしてる感じが気持ち悪い。
   //abstract Test5 : unit -> int with hoge
end
// このInterfaceは以下では使いません;-)

type PropatyTest = class
      val mutable data : string
      // ▼ただのメソッド(property優先なので呼べない)
      member x.Item2(a,b) = x.data + string_of_int(a + b) + " : ---- Item2 : 2 input\n"
      member x.Item2(a) = x.data + string_of_int(a) + " : ---- Item2 : 1 input\n"
      member x.Item2() = x.data + " :  ---- Item2 : 0 input\n"
      // ▼Item2ではただのproperty
      member x.Item2 with get(a,b) = x.data + string_of_int(a + b) + " : Item2 : 2 inputs\n"
      member x.Item2 with get(a)   = x.data + string_of_int(a) + " : Item2 : 1 input\n"
      member x.Item2 with get()    = x.data + " : Item2 : 0 input\n"
      // 以下の行はPropertyと同じ扱いになり二重定義でコンパイルエラー。
      //member x.Item2 = x.data + " :  ---- Item2 : 0 input\n"
      // ▼"Item"だけindexer propertyが可能。
      // 特に指定していないのに"Item"だけ特別扱いなのが気持ち悪い。
      member x.Item  with get(a,b) = x.data + string_of_int(a + b) + " : Item : 2 inputs\n"
      member x.Item  with get(a)   = x.data + string_of_int(a) + " : Item : 1 input\n"
      member x.Item  with get()    = x.data + " : Item : 0 input\n"
      // ▼Item3ではただのproperty
      member x.Item3 with get()    = x.data + " : Item3 : 0 input\n"
      member x.Item3 with get(a)   = x.data + string_of_int(a) + " : Item3 : 1 input\n"
      member x.Item3 with get(a,b) = x.data + string_of_int(a + b) + " : Item3 : 2 inputs\n"
      new () = { data = "PropatyTest : " }
end

let ptest = new PropatyTest()

// ▼indexer propertyでアクセス
// "Item"が呼ばれる。
// 引数1つと2つで別の関数を呼びわけられる。
do printf "PropatyTest.[1]----%s\n" ptest.[1]
do printf "PropatyTest.[1,2]----%s\n" ptest.[1,2]
// ただし、引数0は無理。コンパイルエラーとなる。
//do printf "PropatyTest.----%s\n" ptest.

// ▼メソッドっぽくアクセス
// 一番上で宣言したpropertyの型が優先。それ以外はコンパイルエラーになる。
do printf "PropatyTest.Item(1,2)----%s\n" (ptest.Item(1,2))
//do printf "PropatyTest.Item(1)----%s\n" (ptest.Item(1))
//do printf "PropatyTest.Item----%s\n" ptest.Item
do printf "PropatyTest.Item2(1,2)----%s\n" (ptest.Item2(1,2))
//do printf "PropatyTest.Item2(1)----%s\n" (ptest.Item2(1))
//do printf "PropatyTest.Item2----%s\n" ptest.Item2
//do printf "PropatyTest.Item3(1,2)----%s\n" (ptest.Item3(1,2))
//do printf "PropatyTest.Item3(1)----%s\n" (ptest.Item3(1))
do printf "PropatyTest.Item3----%s\n" ptest.Item3


// 引数がない場合のpropertyは()をつけては呼べない。
//do printf "PropatyTest.Item()----%s\n" (ptest.Item())
//do printf "PropatyTest.Item2()----%s\n" (ptest.Item2())
//do printf "PropatyTest.Item3()----%s\n" (ptest.Item3())

// 結果としていくつかのメソッドは呼び出すことができないようだ。
// 方法があったら誰か教えてー