Type x is less accessible than the value

蓝咒 提交于 2019-12-11 10:48:34

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!