问题
Here's an abstraction of my code:
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")
I get the error Type 'MyType' is less accessible than the value, member, or type: 'val myExternalValue: SubModule.MyType' it is used in
Why can't I have public accessors to a private class instance like this? Note that I'm using the RootModule
in a different file alltogether, and only wish to have myExternalValue
be visible in the other file
回答1:
The idea behind the internal type is that no other program will need to access to the type, and as a result, you should be able to compile a separate app as if that type does not exist. However, you have violated that assumption. In particular, how does the calling program know how to call any methods on the type?
You could fix this by marking myExternalValue
as internal.
回答2:
You have hidden MyType, but myExternalValue need to tell the caller what type is return
there are two way to do this:
option 1: return an object, and use reflection to get value or to invoke function
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
usage:
open RootModule
printfn "%d" <| RootModule.myExternalValue?GetStringLength
option 2: exposing behavior, but hiding the real type
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
usage:
printfn "%d" <| RootModule.myExternalValue.GetStringLength
来源:https://stackoverflow.com/questions/18811609/type-x-is-less-accessible-than-the-value