Что происходит с видимостью защищенного переопределенного метода в F #? - PullRequest
0 голосов
/ 14 марта 2020

У меня есть разные результаты для отражения в зависимости от языка: C# против 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 содержит SendAsync, Dispose, MemberwiseClone и Finalize.

Теперь 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, Publi c, Виртуальный, HideBySig

WTF ?! Где обещанное уважение к protected модификатору видимости?

1 Ответ

3 голосов
/ 14 марта 2020

Мне жаль говорить, что они никогда не обещали уважения к модификатору видимости.

В F # 4.1 Spe c, раздел 10.5:

Аннотации доступности

В таблице перечислены возможности, которые могут отображаться в коде пользователя:

publi c

Нет ограничений на доступ.

частный

Доступ разрешен только из охватывающего типа, модуля или группы объявлений пространства имен.

внутренняя

Доступ разрешен только изнутри сборки или из сборок, имя которых указано с помощью атрибута InternalsVisibleTo в текущей сборке.

...

Скомпилированная в CLI форма всех непубличных c сущностей внутренняя .

Примечание: Семейная и защищенная спецификации не поддерживаются в этой версии языка F #.

К сожалению, вы ожидаете увидеть ожидаемое поведение.

...