如何在F#中调用参数名称相同的C#重写方法?
在F#中调用参数命名相同的C#重载方法
在F#里调用这种参数命名完全一致但类型不同的C#重载方法,确实容易让编译器犯懵,我给你几个靠谱的解决方案:
1. 显式指定参数类型
直接给关键参数加上类型注解,让编译器明确知道你要匹配哪个重载。针对你给出的两个方法,示例如下:
open System open System.Collections.Generic open System.IO open System.Threading.Tasks open System.Threading // 假设已经实例化了trainingApi: ITrainingApi let projectId = Guid.NewGuid() let cancellationToken = CancellationToken.None // 调用接收IEnumerable<Stream>和IList<Guid>的重载 let imageStreams : IEnumerable<Stream> = [| new MemoryStream() |] :> IEnumerable<Stream> let tagGuids : IList<Guid> = [| Guid.NewGuid() |] :> IList<Guid> task { let! result = trainingApi.CreateImagesFromDataAsync( projectId = projectId, imageData = imageStreams, tagIds = tagGuids, cancellationToken = cancellationToken ) return result } // 调用接收Stream和IList<string>的重载 let singleImageStream = new MemoryStream() let tagStrings : IList<string> = [| "tag1"; "tag2" |] :> IList<string> task { let! result = trainingApi.CreateImagesFromDataAsync( projectId = projectId, imageData = singleImageStream, tagIds = tagStrings, cancellationToken = cancellationToken ) return result }
2. 给方法添加类型注解强制匹配重载
你可以先把方法绑定到一个变量上,明确指定它的签名,这样后续调用就不会混淆了:
// 绑定第一个重载(IEnumerable<Stream> + IList<Guid>) let createImagesWithGuids = (trainingApi.CreateImagesFromDataAsync : Guid -> IEnumerable<Stream> -> IList<Guid> option -> CancellationToken -> Task<CreateImageSummaryModel>) // 绑定第二个重载(Stream + IList<string>) let createImagesWithStrings = (trainingApi.CreateImagesFromDataAsync : Guid -> Stream -> IList<string> option -> CancellationToken -> Task<CreateImageSummaryModel>) // 调用的时候就清晰了 task { let! result1 = createImagesWithGuids projectId imageStreams (Some tagGuids) cancellationToken let! result2 = createImagesWithStrings projectId singleImageStream (Some tagStrings) cancellationToken return (result1, result2) }
3. 使用位置参数配合类型转换
如果觉得命名参数太繁琐,也可以用位置传递,同时给参数加上类型转换,让编译器识别重载:
task { // 调用第一个重载 let! result1 = trainingApi.CreateImagesFromDataAsync( projectId, imageStreams :> IEnumerable<Stream>, tagGuids :> IList<Guid>, cancellationToken ) // 调用第二个重载 let! result2 = trainingApi.CreateImagesFromDataAsync( projectId, singleImageStream, tagStrings :> IList<string>, cancellationToken ) return (result1, result2) }
核心原因其实是F#的类型推断机制:当两个重载的参数名称完全相同,仅类型不同时,编译器无法通过命名参数自动推断出你要调用的版本,必须通过显式的类型信息来引导它。
内容的提问来源于stack exchange,提问作者baio
相关产品推荐
相关产品推荐

