From the F# 4.0 spec [PDF]:
The CLI compiled form of all non-public entities is
internal
.
In my main project I have a function defined as
namespace MyNamespace.Foo
module Bar =
module Baz =
let private myFun ...
In the main project's ``AssemblyInfo.fs` I have
[<assembly: InternalsVisibleTo("MyNamespace.Tests")>]
(I've double-checked the name.)
However, in the test assembly (also F#), I get an error when referencing myFun
saying The value 'myFun' is not accessible from this code location.
Everything works fine if I remove private
from the definition of myFun
.
Strangely enough I am also able to call the private myFun
from a C# project even without InternalsVisibleTo
.
Why is the private myFun
not accessible from the test assembly when private
entities compile to internal
and I've specified InternalsVisibleTo
on the main assembly?
I think there is a difference between the language level and the compiled code level.
At language level, private
behaves as private, so you are only allowed to call the function within the module. If you mark the binding as internal
, it will behave as internal and you'll be able to call it from the same assembly.
At compiled code level, private
s compiled as internal
, presumably so that you can use things like closures and sequence expressions, but the F# compiler knows that this is just a compilation artifact.
I have not tried this, but I'd guess that if you referenced the assembly from C# then it would behave as internal
because the C# compiler does not understand the special metadata that the F# compiler puts in to mark the let binding.