Reputation: 13983
I have different result for reflection depending on the language: 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
contains SendAsync
, Dispose
, MemberwiseClone
, and Finalize
.
Now 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
contains only three methods, SendAsync
is absent.
However, if I use Public
binding flag, methods
contains more entries including SendAsync
:
let methods = typeof<TestHandler>.GetMethods(BindingFlags.NonPublic ||| BindingFlags.Instance ||| BindingFlags.Public)
However, there is a difference in RuntimeMethodInfo
of C# and F# versions.
For C# Attributes
property is:
- PrivateScope, Family, Virtual, HideBySig,
whereas for F# it is:
- PrivateScope, Public, Virtual, HideBySig
WTF?! Where is promised respect for protected
visibility modifier?
Upvotes: 0
Views: 74
Reputation: 12667
I'm sorry to say that they never did promise respect for the visibility modifier.
In the F# 4.1 Spec, section 10.5:
Accessibility Annotations
The table lists the accessibilities that can appear in user code:
public
No restrictions on access.
private
Access is permitted only from the enclosing type, module, or namespace declaration group.
internal
Access is permitted only from within the enclosing assembly, or from assemblies whose name is listed using the InternalsVisibleTo attribute in the current assembly.
...
The CLI compiled form of all non-public entities is internal.
Note: The family and protected specifications are not supported in this version of the F# language.
What reflection is showing you is unfortunately, expected behavior.
Upvotes: 3