简体   繁体   English

F#中的通用模块

[英]Generic modules in F#

In C#, I can compile 在C#中,我可以编译

static class Foo<T> { /* static members that use T */ }

The result is generic and is not instantiable. 结果是通用的,不可实例化。

What is the equivalent F# code? 什么是等效的F#代码? module<'a> doesn't compile, and type Foo<'a> is instantiable. module<'a>不编译, type Foo<'a>是可实例化的。

The other answers so far each have part of the picture... 到目前为止,其他答案都有部分图片......

type Foo<'a> private() =          // '
    static member Blah (a:'a) =   // '
        printfn "%A" a

is great. 是很棒的。 Disregard what Reflector generates, you cannot instantiate this class from within the F# assembly (since the constructor is private), so this works well. 忽略Reflector生成的内容,你不能在F#程序集中实例化这个类(因为构造函数是私有的),所以这很好用。

F# does allow static constructors as well, the syntax is to include 'static let' and 'static do' statements in the class (which work analogously to how 'let' and 'do' work as part of the primary constructor body for instances). F#也允许使用静态构造函数,语法是在类中包含'static let'和'static do'语句(类似于'let'和'do'如何作为实例的主构造函数体的一部分工作) 。 A full example: 一个完整的例子:

type Foo<'a> private() =             // '
    static let x = 0
    static do printfn "Static constructor: %d" x
    static member Blah (a:'a) =      // '
        printfn "%A" a

//let r = new Foo<int>() // illegal
printfn "Here we go!"
Foo<int>.Blah 42
Foo<string>.Blah "hi"

I thought at first that this would be close to what you wanted: 我一开始以为这会接近你想要的东西:

type Foo<'a> private() =   
    static member Blah (a:'a) =
       printfn "%A" a

Being like the idiom pre c# 2.0 of being instantiable only via reflection or by the class itself (which hopefully wouldn't do it). 就像只能通过反射或类本身(希望不会这样做)实例化的成语前c#2.0。

however this is compiled down to: 但是这被编译为:

[Serializable, CompilationMapping(SourceConstructFlags.ObjectType)]
public class Foo<a>
{
    internal Foo() {...}

    public static void Blah(a a) {...}
}

Which implies that other classes within the f# assembly could instantiate it. 这意味着f#程序集中的其他类可以实例化它。

However the ever informed Brian has indicated that the f# compiler respects this private setting despite the underlying CLR type which means that the only way to instantiate would be via reflection or by using something like the InternalsVisibleTo attribute. 然而,知情的Brian已经指出f#编译器尊重这个私有设置,尽管底层的CLR类型意味着实例化的唯一方法是通过反射或使用类似InternalsVisibleTo属性的东西。

This may still be acceptable for your needs... 这可能仍然可以满足您的需求......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM