F#中的通用构造函数

时间:2014-01-07 02:03:09

标签: generics constructor f#

type Foo(size: int,data: 'T []) =
    new(data: float []) =
        Foo(sizeof<float>,data)
    new(data: int []) =
        Foo(sizeof<int>,data) //error: f# thinks that data is float []
    member this.Size() = size

基本上我需要几个带有通用数组'T []的构造函数,我只关心'T的大小。

我想这样用:

Foo([|1,2,3,4|]).Size() // prints size of int
Foo([|1.f,2.f,3.f,4.f|]).Size() // prints size of float

我该怎么做?

UPDATE1:

我刚才意识到我不能让编译器推断出尺寸,我必须手动完成。

type Foo<'T>(size: int,data: 'T []) =
    new(data: float []) =
        Foo(4,data)
    new(data: int []) =
        Foo(16,data)
    new(data: Vector3 []) =
        Foo(Vector3.SizeInBytes,data)
    member this.Size() = size

这可能吗?

当我这样做的时候 Foo([|new Vector3(1.f,1.f,1.f)|]我希望Foo属于Foo<Vector3>,因此数据应为数据类型:Vector3 []

1 个答案:

答案 0 :(得分:2)

试试这个:

type Foo<'T>(size: int, data: 'T []) =
    new(data: 'T []) =
        Foo(sizeof<'T>, data)
    member this.Size() = size

请注意,在测试时应小心。当您致电Foo([|1,2,3,4|])时,它会推断T类型为int * int * int * int。使用分号分隔数组元素:

Foo([|1;2;3;4|]).Size()           // 4
Foo([|1.f;2.f;3.f;4.f|]).Size()   // 4
Foo([|1.m;2.m;3.m;4.m|]).Size()   // 16

<强>更新
鉴于您的更新问题,您似乎正在尝试进行一些部分专业化。我建议尝试在泛型类本身中执行此操作,毕竟,.NET中泛型的全部要点是您不必为要使用的每种类型设置不同的策略。相反,使用静态工厂创建一个单独的类型,以便为您要创建的各种类型生成具有多个重载的Foo个对象:

type Foo<'T>(size: int, data: 'T []) =
    member this.Size() = size

type Foo =
    static member from (data : int[]) = Foo(16, data)
    static member from (data : float[]) = Foo(4, data)
    static member from (data : Vector3[]) = Foo(Vector3.SizeInBytes, data)
    static member from (data : 'T[]) = Foo(sizeof<'T>, data)

Foo.from([|1;2;3;4|]).Size()                // 16
Foo.from([|1.f;2.f;3.f;4.f|]).Size()        // 4
Foo.from([|Vector3(1.f,1.f,1.f)|]).Size()   // Vector3.SizeInBytes
Foo.from([|1.m;2.m;3.m;4.m|]).Size()        // 16