用F#语言覆盖C#类中的方法会使该方法无法内省吗?

kno*_*cte 4 c# reflection f# system.reflection c#-to-f#

我有以下C#类:

public class Foo {
    protected virtual void Bar (){
    }
}

public class Baz : Foo {
    protected override void Bar (){
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我反省它们,方法Bar总是在那里:

[<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")
Run Code Online (Sandbox Code Playgroud)

结果是这is not null两种情况.

但是,当我对F#类执行相同操作时,结果会有所不同:

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")
Run Code Online (Sandbox Code Playgroud)

但为什么???如果我的课程是用F#制作的,我不能通过反射获得方法吗?我很沮丧.

Jar*_*Par 8

你没有看到它的原因是因为FSharpBaz.Bar发射public和不发射protected.您可以通过查看ildasm中的代码来验证这一点.这实际上是完全合法的行为,将在CLI规范的第8.5.3.2节中介绍

当类型定义覆盖继承定义的虚方法时,可访问性在两个定义中应相同,或者覆盖定义应允许比原始定义更多的访问.

至于F#public在这里使用的原因,这只是成员定义的默认值

如果没有使用访问说明符,则默认为public,除了类型中的let绑定,该类型始终是该类型的私有(Link)