Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# actually compiles private members as internal in IL. Bug?

Tags:

.net

f#

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?

like image 731
Philip P. Avatar asked Sep 10 '13 11:09

Philip P.


People also ask

What does ⟨F⟩ mean?

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.

What does the letter F mean in math?

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 ).

What does F stand for in the Etruscan alphabet?

In the Etruscan alphabet, 'F' probably represented /w/, as in Greek, and the Etruscans formed the digraph 'FH' to represent /f/.

Is the letter F doubled at the end of words?

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.


1 Answers

From the F# 3.0 specification: The CLI compiled form of all non-public entities is internal.

like image 176
Eugene Fotin Avatar answered Oct 12 '22 09:10

Eugene Fotin