I have the following C# classes:
public class Foo {
protected virtual void Bar (){
}
}
public class Baz : Foo {
protected override void Bar (){
}
}
If I introspect them, the method Bar is always there:
[<EntryPoint>]
let main args =
let methodFromFoo = typedefof<Foo>.GetMethod("Bar", BindingFlags.Instance ||| BindingFlags.NonPublic)
if (methodFromFoo <> null) then
Console.WriteLine ("methodFromFoo is not null")
else
Console.WriteLine ("methodFromFoo is null")
let methodFromBaz = typedefof<Baz>.GetMethod("Bar", BindingFlags.Instance ||| BindingFlags.NonPublic)
if (methodFromBaz <> null) then
Console.WriteLine ("methodFromBaz is not null")
else
Console.WriteLine ("methodFromBaz is null")
The result of this is is not null
for both cases.
However, when I do the same with an F# class the result is different:
type FSharpBaz() =
inherit Foo()
override this.Bar () =
Console.WriteLine ("yeh")
[<EntryPoint>]
let main args =
let methodFromFsharp = typedefof<FSharpBaz>.GetMethod("Bar", BindingFlags.Instance ||| BindingFlags.NonPublic)
if (methodFromFsharp <> null) then
Console.WriteLine ("methodFromFsharp is not null")
else
Console.WriteLine ("methodFromFsharp is null")
But why??? Cannot I get the method via reflection if my class is made with F#? I'm devastated.
The reason why you don't see it is because FSharpBaz.Bar
is emitted as public
and not protected
. You can verify this by looking at the code in ildasm. This is actually completely legal behavior and is covered in section 8.5.3.2 of the CLI spec
When a type defines a virtual method that overrides an inherited definition, the accessibility shall either be identical in the two definitions or the overriding definition shall permit more access than the original definition.
As to why F# uses public
here, that is simply the default for member definitions
If no access specifier is used, the default is public, except for let bindings in a type, which are always private to the type (Link)
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