I always assumed that the access control keywords in F# (public
, private
, internal
) work in the same way as they do in C#. Indeed from the MSDN documentation Access Control (F#):
- public indicates that the entity can be accessed by all callers.
- internal indicates that the entity can be accessed only from the same assembly.
- private indicates that the entity can be accessed only from the enclosing type or module.
This seems to be pretty consistent with my assumption and also multiple answers on the topic provided here at SO.
However, when I poked into the compiled code with Reflector, I discovered that all those members declared as private are actually compiled as internal (assembly visibility), which is not matching the documentation.
To avoid any doubt, I have created as small test to confirm this.
F# code:
// Make internals visible to other assemblies
[<assembly:InternalsVisibleTo("MyCSharpAssembly")>]
// OK. Expect: "internal static class PrivateModule" in C#
module private PrivateModule =
// FAIL. Expect: "private static void privateStaticMethod()" in C#
let private privateStaticMethod() = ignore()
// OK. Expect: "internal class InternalClass" in C#
type private InternalClass() =
// FAIL. Expect: "private int privateInstanceField" in C#
let privateInstanceField = 0
// FAIL. Expect: "private static int privateStaticField" in C#
static let privateStaticField = 0
// FAIL. Expect: "private int privateInstanceMethod()" in C#
let privateInstanceMethod() = privateInstanceField
// FAIL. Expect: "private in PrivateInstanceMember()" in C#
member private this.PrivateInstanceMember() = privateInstanceField
// OK. Expect: "internal int InternalInstanceMember" in C#
member internal this.InternalInstanceMember() = privateStaticField
I have put together a bit of C# code to make sure I'm not imagining things.
C# test code, and everything compiles.
public class TestVisibility
{
// This is a demo to verify that the members are indeed
// internal (assembly) and can be accessed from C# if the
// F# assembly is compiled with [<assembly:InternalsVisibleTo("C# assembly")>]
public void Run()
{
// All of these compile.
PrivateModule.privateStaticMethod();
InternalClass x = new InternalClass();
int a = InternalClass.privateStaticField;
var b = x.InternalInstanceMember();
var c = x.PrivateInstanceMember();
var d = x.privateInstanceField;
var f = x.privateInstanceMethod();
}
}
I used VS2012, targeting .NET 4.0, all settings are default. Tried both Debug and release modes with same results.
Question: What is actual expected behaviour as per design? Is it a bug? Or I am doing something wrong?
Suggestion: If this is intended behaviour, perhaps it might be a good idea to explicitly mention this in documentation somewhere?
This sound is usually considered to be an allophone of /h/, which is pronounced in different ways depending upon its context; Japanese /h/ is pronounced as [ɸ] before /u/. In Welsh orthography, ⟨f⟩ represents /v/ while ⟨ff⟩ represents /f/. In Slavic languages, ⟨f⟩ is used primarily in words of foreign (Greek, Latin, or Germanic) origin.
In countries such as the United States, the letter "F" is defined as a failure in terms of academic evaluation. Other countries that use this system include Saudi Arabia, Venezuela, and the Netherlands. In the hexadecimal number system, the letter "F" or "f" is used to represent the hexadecimal digit fifteen (equivalent to 15 10 ).
In the Etruscan alphabet, 'F' probably represented /w/, as in Greek, and the Etruscans formed the digraph 'FH' to represent /f/.
It is often doubled at the end of words. Exceptionally, it represents the voiced labiodental fricative / v / in the common word "of". F is the twelfth least frequently used letter in the English language (after C, G, Y, P, B, V, K, J, X, Q, and Z ), with a frequency of about 2.23% in words.
From the F# 3.0 specification: The CLI compiled form of all non-public entities is internal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With