GeneralizableValueAttribute

特に意味はないのですが、頭痛を癒すためにVisual Studioを立ち上げました。ただのひとり遊びです。

type Person() = class end
type Dog()    = class end
type Cat()    = class end

type MyCollection<'T>() =
    static let arr = new ResizeArray<'T>() // static がミソだよ!
    member self.Add = arr.Add
    override self.ToString() = typeof<'T>.Name + "\t× " + arr.Count.ToString()

[<GeneralizableValue>]
let collection<'T> = new MyCollection<'T>()

[<EntryPoint>]
let Main args =
    collection.Add <| Person()
    collection.Add <| Dog()
    collection.Add <| Cat()
    collection.Add <| Dog()
    collection.Add <| Cat()
    collection.Add <| Cat()
    
    printfn "%A" (collection<Person>)
    printfn "%A" (collection<Dog>)
    printfn "%A" (collection<Cat>)
    
    0

Person  × 1
Dog × 2
Cat × 3
続行するには何かキーを押してください . . .
Main関数内だけ見るとなかなか不思議。
手当たり次第に詰め込んだのに、中の人がきちんと仕分けしてくれています。


ちなみに、GeneralizableValueAttribute を付けると関数に変換されるようです。
追記:コメント欄で いげ太さんにご指摘いただきましたが、この属性の有無は関係ないようです。
上の例だと以下のように展開されていました。

[GeneralizableValue]
public static MyCollection<T> collection<T>()
{
    return new MyCollection<T>();
}