Я могу сделать это (F # FSI):
let o = Object()
let m = o.GetHashCode;; //[1]
val o : Object
val m : (unit -> int)
что делает метод GetHashCode
доступным и вызываемым как первоклассную функцию в привязке m
:
m ();;
val it : int = 12345678
Как бы я это сделал, если бы для рассматриваемого метода существовала перегрузка, скажем, дополнительная Object.GetHashCode(int whateverParameter)
? Теперь я могу получить только «первый» (самый короткий?) метод. Могу ли я предоставить дополнительную информацию о типе параметра в вызове 1, чтобы указать, какую перегрузку я хочу?
ИЗМЕНИТЬ
Спасибо за ваш вклад до сих пор. Аннотации типов кажутся правильным выбором. Хотя для моего более сложного примера я все еще не могу понять, как это правильно сделать.
Вот конкретные сигнатуры методов того типа, с которым я имею дело (он взят с сайта octokit.net библиотека, поэтому вам нужно что-то вроде #r "nuget:include=Octokit"
в fsi [с /langversion:preview
]).
Я заинтересован в получении конкретной перегрузки GetAllForRepository
, кстати, первой в списке: GetAllForRepository(string, string)
.
open Octokit
let client = GitHubClient(...)
client.Issue.GetType().GetMethods()
|> Seq.filter (fun methodInfo -> methodInfo.Name.StartsWith("GetAllForRepository"))
|> Seq.map (fun methodInfo -> (methodInfo.GetParameters(), methodInfo.ReturnType))
|> Seq.map (fun (parameterInfos, returnType) ->
(parameterInfos |> Seq.map (fun parameterInfo -> parameterInfo.ParameterType.FullName), returnType.FullName))
val it : seq<seq<string> * string> =
seq
[(seq ["System.String"; "System.String"],
"System.Threading.Tasks.Task`1[[System.Collections.Generic.IReadOnlyList`1[[Octokit.Issue, Octokit, Version=0.48.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]");
(seq ["System.Int64"],
"System.Threading.Tasks.Task`1[[System.Collections.Generic.IReadOnlyList`1[[Octokit.Issue, Octokit, Version=0.48.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]");
(seq ["System.String"; "System.String"; "Octokit.ApiOptions"],
"System.Threading.Tasks.Task`1[[System.Collections.Generic.IReadOnlyList`1[[Octokit.Issue, Octokit, Version=0.48.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]");
(seq ["System.Int64"; "Octokit.ApiOptions"],
"System.Threading.Tasks.Task`1[[System.Collections.Generic.IReadOnlyList`1[[Octokit.Issue, Octokit, Version=0.48.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]");
(seq ["System.String"; "System.String"; "Octokit.RepositoryIssueRequest"],
"System.Threading.Tasks.Task`1[[System.Collections.Generic.IReadOnlyList`1[[Octokit.Issue, Octokit, Version=0.48.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]");
(seq ["System.Int64"; "Octokit.RepositoryIssueRequest"],
"System.Threading.Tasks.Task`1[[System.Collections.Generic.IReadOnlyList`1[[Octokit.Issue, Octokit, Version=0.48.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]");
(seq
["System.String"; "System.String"; "Octokit.RepositoryIssueRequest";
"Octokit.ApiOptions"],
"System.Threading.Tasks.Task`1[[System.Collections.Generic.IReadOnlyList`1[[Octokit.Issue, Octokit, Version=0.48.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]");
(seq
["System.Int64"; "Octokit.RepositoryIssueRequest";
"Octokit.ApiOptions"],
"System.Threading.Tasks.Task`1[[System.Collections.Generic.IReadOnlyList`1[[Octokit.Issue, Octokit, Version=0.48.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]")]
Теперь самая короткая подпись принимает один параметр int64
:
let m = client.Issue.GetAllForRepository;;
val m :
(int64 ->
System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>)
Я могу явно объявить подпись и получить тот же метод:
let m: (int64 -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>) = client.Issue.GetAllForRepository;;
val m :
(int64 ->
System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>)
Но доступ к версии (string, string)
дает мне:
let m: (string -> string -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>) = client.Issue.GetAllForRepository;;
let m: (string -> string -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>) = client.Issue.GetAllForRepository;;
--------------------------------------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(33,117): error FS0193: Type constraint mismatch. The type
'string'
is not compatible with type
'int64'
Аналогичная ошибка возникает при попытке доступа к любой другой перегрузке с более чем одним параметром:
let m: (int64 -> Octokit.RepositoryIssueRequest -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>) = client.Issue.GetAllForRepository;;
let m: (int64 -> Octokit.RepositoryIssueRequest -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>) = client.Issue.GetAllForRepository;;
-------------------------------------------------------------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(37,140): error FS0001: This expression was expected to have type
'Octokit.RepositoryIssueRequest -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>'
but here has type
'System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>'
let m: (int64 -> Octokit.RepositoryIssueRequest -> Octokit.ApiOptions -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>) = client.Issue.- GetAllForRepository;;
let m: (int64 -> Octokit.RepositoryIssueRequest -> Octokit.ApiOptions -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>) = client.Issue.GetAllForRepository;;
-----------------------------------------------------------------------------------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(36,162): error FS0001: This expression was expected to have type
'Octokit.RepositoryIssueRequest -> Octokit.ApiOptions -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>'
but here has type
'System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>'
Итак, я делаю что-то неправильно в отношении аннотаций типов?
let m: char -> int = "Hello".IndexOf;;
, выбираяSystem.String.IndexOf(char)
вместоSystem.String.IndexOf(string)
. А вот сигнатуры предполагаемых мною методов (из библиотеки octokit.net) посложнее, вродеTask<IReadOnlyList<Issue>> GetAllForRepository(string owner, string name)
. Возможно, это связано с возвращаемым значениемTask<...>
. - person Christian   schedule 11.01.2021m: ((string * string) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Octokit.Issue>>)
? - person Mark Pattison   schedule 13.01.2021