这是我的代码的抽象:
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
答案 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