0

根据语言的不同,我有不同的反射结果:C# vs F#

C#

public abstract class TestHandler : HttpMessageHandler
{
    public abstract Task<HttpResponseMessage> MockableSendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }
}

var methods = typeof(TestHandler).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);

methods包含SendAsyncDisposeMemberwiseCloneFinalize

现在F#

open System.Net.Http
open System.Threading
open System.Threading.Tasks
open System.Reflection

[<AbstractClass>]
type TestHandler() = 
    inherit HttpMessageHandler()
    abstract member MockableSendAsync: HttpRequestMessage * CancellationToken -> Task<HttpResponseMessage>
    override this.SendAsync(request, cancellationToken) = this.MockableSendAsync(request, cancellationToken)

let methods = typeof<TestHandler>.GetMethods(BindingFlags.NonPublic ||| BindingFlags.Instance)

methods只包含三个方法,SendAsync不存在。

但是,如果我使用Public绑定标志,则methods包含更多条目,包括SendAsync

let methods = typeof<TestHandler>.GetMethods(BindingFlags.NonPublic ||| BindingFlags.Instance ||| BindingFlags.Public)

RuntimeMethodInfo但是, C# 和 F# 版本存在差异。

对于 C#Attributes属性是:
- PrivateScope、Family、Virtual、HideBySig、

而对于 F#,它是:
- PrivateScope、Public、Virtual、HideBySig

怎么回事?!承诺尊重protected可见性修饰符在哪里?

4

1 回答 1

3

我很遗憾地说他们从未承诺尊重可见性修饰符。

在 F# 4.1 规范中,第 10.5 节:

可访问性注释

下表列出了可以出现在用户代码中的辅助功能:

上市

访问没有限制。

私人的

仅允许从封闭类型、模块或命名空间声明组进行访问。

内部的

仅允许从封闭程序集内访问,或者从使用当前程序集中的 InternalsVisibleTo 属性列出名称的程序集进行访问。

...

所有非公共实体的 CLI 编译形式都是internal

注意:此版本的 F# 语言不支持系列规范和受保护规范。

不幸的是,反射向您展示的是预期的行为。

于 2020-03-14T16:30:14.077 回答