1

这是我的代码的抽象:

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在另一个文件中可见

4

2 回答 2

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
于 2013-09-15T15:01:37.837 回答
1

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

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

于 2013-09-15T11:06:16.847 回答