类型x的可访问性低于值

时间:2013-09-15 11:02:21

标签: f#

这是我的代码的抽象:

module RootModule

module private SubModule = // I want everything in this module to be inaccessible from outside the file
    let getLength s = String.Length s
    type MyType (s: string) =
        let _str = s
        member this.GetStringLength = getLength _str // for sake of simplicity, a bogus method

let myExternalValue = new SubModule.MyType("Hello")

我收到错误Type 'MyType' is less accessible than the value, member, or type: 'val myExternalValue: SubModule.MyType' it is used in

为什么我不能拥有像这样的私有类实例的公共访问器?请注意,我在一个不同的文件中使用RootModule,并且只希望在其他文件中显示myExternalValue

2 个答案:

答案 0 :(得分:1)

内部类型背后的想法是没有其他程序需要访问该类型,因此,您应该能够编译一个单独的应用程序,就好像该类型不存在一样。但是,你违反了这个假设。特别是,调用程序如何知道如何调用类型上的任何方法?

您可以通过将myExternalValue标记为内部来解决此问题。

答案 1 :(得分:1)

你隐藏了MyType,但myExternalValue需要告诉调用者返回什么类型

有两种方法可以做到这一点:

选项1:返回一个对象,并使用反射来获取值或调用函数

module RootModule

open System.Reflection

module private SubModule =
    let getLength s = String.length s

    type MyType (s: string) =
        let _str = s
        member this.GetStringLength with get() = getLength _str

let (?) obj property =
    let flags = BindingFlags.NonPublic ||| BindingFlags.Instance
    obj.GetType().GetProperty(property, flags).GetValue(obj) |> unbox

let myExternalValue = SubModule.MyType("Hello") :> obj

用法:

open RootModule
printfn "%d" <| RootModule.myExternalValue?GetStringLength

选项2:暴露行为,但隐藏真实类型

module RootModule

type RootType =
    abstract member GetStringLength : int

module private SubModule =
    let getLength s = String.length s

    type MyType (s: string) =
        let _str = s
        interface RootType with
            member this.GetStringLength with get() = getLength _str

let myExternalValue = SubModule.MyType("Hello") :> RootType

用法:

printfn "%d" <| RootModule.myExternalValue.GetStringLength