An interesting bit of F# behaviour
In one assembly, define a public static class in C#:
In another do something similar in F#:
which Reflector tells us is equivalent to
inside namespace ClassLibrary1
. Now create another F# library referencing the previous two containing
The first line compiles; the second doesn't, failing with compile error error FS0039: The type 'Module1' is not defined
.
Clearly the CompilationMapping
is being sniffed by the typeof
operation, because that is the only difference between the two.
4 comments :
It's not CompilationMapping, rather it's because typeof<AModule> is not allowed in F#. There's no good technical reason really, and we have a bug logged to remedy this, but it's a low priority since it's uncommon to want this for any real scenario.
The question is how it detected, in the separate assembly, that the code was an F# module rather than a C# static class -- and at the IL level the CompilationMapping attribute is the most blatant difference that can be what says "this static class is an F# module".
The use case is a simple piece of reflection -- wanting from one assembly to get the MethodInfo for one of the functions in the module, the sort of thing that in C# would just be typeof(Module1).GetMethod("Hello")
F# assemblies contain their own metadata (stored as a resource, see e.g. FSharp.PowerPack.Metadata), and it is the 'extra F# metadata' that identifies a static class as an F# module.
Thatks for the detail -- I stand corrected on the precise detection mechanism.
The point however remains that tyepof<'T> is examining F# fingerprints (not just the particulargaudy red herring I first spotted) and filtering accordingly. This isn't the obvious behaviour cross-assembly (where the source language isn't an obvious part of the public interface), so it's still worth flagging.
Post a Comment