【问题标题】:Polymorphism with Generics and common fields具有泛型和公共字段的多态性
【发布时间】:2018-04-01 12:19:59
【问题描述】:

这个question 的回答有点相似,但是这个问题需要在强制参数类型有一些公共字段的同时使用泛型。

type Document = {
    Name: string
    Version: string
}

let inline requestData<'t> (document: 't) =
    Console.WriteLine(document.Name)
    Console.WriteLine(document.Version)

测试

requestData<Document>({Name = "test"; Version="259723983"})

我得到的错误是

根据此程序点之前的信息查找不确定类型的对象。在此程序指向之前可能需要一个类型注释来约束对象的类型。这可能会解决查找问题。

编辑

let inline requestData<'t> (document: 't) =
    let name = (^document: (member Name: string)(document))

此处不能使用声明的类型参数t',因为在编译时无法解析类型参数。

【问题讨论】:

  • requestData 应该与您链接的答案中的 someComplexFun 相同 - 您只需要声明静态解析的成员访问权限,而不是直接调用 document.Name

标签: f#


【解决方案1】:

您需要限制类型而不是文档参数。此外,'T 表示法适用于通常的泛型,而不是 SRTP。如果你坚持要添加类型参数(不知道为什么),你可以这样定义它:

let inline requestData< ^a when ^a : (member Name : string)  > x =
    Console.WriteLine(^a: (member Name: string)(x))

这样你就可以这样写:

open System

type Document = {
    Name: string
    Version: string
}

type OtherDoc = {
    Name: string
    Version: string
}

let doc1 = {Document.Name = "Joe"; Version = "123"}
let doc2 = {OtherDoc.Name = "Jim"; Version = "456"}

requestData doc2
requestData doc1

或者:

requestData<Document> doc1 //Joe
requestData<OtherDoc> doc2 //Jim

这将是一个错误:

requestData<Document> doc2 //error FS0001: This expression was expected to have type...

【讨论】:

  • 感谢您的回答。是的,我了解到我不能将类型约束与泛型一起使用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多