Interface 在F#中,如何在lambda表达式中转换接口?
我发现F#中的接口概念与C#有很大的不同 但是,在实现以下接口时:Interface 在F#中,如何在lambda表达式中转换接口?,interface,f#,Interface,F#,我发现F#中的接口概念与C#有很大的不同 但是,在实现以下接口时: type IVisit = abstract member lastname: string with get abstract member firstname: string with get abstract member mi: string with get abstract member birthdate: Nullable<DateTime> with get
type IVisit =
abstract member lastname: string with get
abstract member firstname: string with get
abstract member mi: string with get
abstract member birthdate: Nullable<DateTime> with get
abstract member appointmentTime : System.Nullable<DateTime> with get
abstract member tservice : System.Nullable<DateTime> with get
abstract member postingTime : System.Nullable<DateTime> with get
abstract member chartNumber : System.Nullable<int> with get
type Visit =
interface IVisit with
member this.lastname = "lastname"
member this.firstname = "FirstName"
member this.mi = "mi"
member this.birthdate = Nullable(DateTime(2020, 1, 1))
member this.appointmentTime = Nullable(DateTime(2020, 1, 1))
member this.tservice = Nullable(DateTime(2020, 1, 1))
member this.postingTime = Nullable(DateTime(2020, 1, 1))
member this.chartNumber = Nullable(0)
正在尝试使用Visit:>IVisit.lastname=…,或Visit:#IVisit.lastname=…,强制转换“Visit”。。。也失败了。我相信这很简单,这是怎么做到的
谢谢您的帮助。您在第二个代码段中使用的语法是用于记录初始化的代码段。但是,您希望创建接口的实例 您可以通过创建一个类来实现这一点,但是您的类定义还没有完全实现,因为它没有构造函数。所以,你需要一些大致的东西:
type Visit(first:string, last:string) =
interface IVisit with
member x.first = first
member x.last = last
这会变得相当麻烦,所以我会使用另一个F#特性,匿名对象表达式,它允许您创建一个没有类的接口实例:
{ new IVisit with
member x.first = "Yadda"
member x.last = "Yadda" }
使用此选项,您的代码将如下所示:
let context = Wsdl1.GetBasicHttpBinding_IMedicalService()
let GetScheduleAsync (tableDate : DateTime) =
async {
let data = context.GetOfficeScheduleAsync(tableDate) |> Async.AwaitTask
return data |> Seq.map(fun q ->
{ new IVisit with
member this.mi = "??"
member this.lastname = q.lastname
member this.firstname = q.firstname
member this.birthdate = q.birthdate
member this.appointmentTime = q.appointment_time
member this.tservice = q.service_time
member this.postingTime = q.posting_time
member this.chartNumber = q.chart_number })
}
|> Async.StartAsTask
也就是说,我真的不明白为什么这里需要一个接口,而不是普通的F#record。即使要从C#使用此库,记录看起来也会像普通类。要使用接口创建值,必须使用对象表达式语法,或实现类(),您所做的是尝试创建类型为“Visit”的记录,而不是记录。我的C#代码使用接口作为DI,例如List()。我的想法是,要在C#中统计List(),F#记录必须实现IVisit。我错了吗?谢谢。@AlanWayne是的,没错-但是我不明白为什么对于一个简单的记录类型需要依赖注入。记录只是存储数据,它是由编译器生成的,因此它是正确的,我怀疑您是否会想用另一个实现来替换它……在C代码中,我有多个不同的记录类型,它们有更多的字段,然后用IVisit表示。然而,我的一些方法只依赖于IVisit中的字段。因此,允许不同类型共享公共IVisit接口,我可以将相同的方法应用于不同的结构。在这两种情况下,我是否可以使用匿名对象来统计C#List?或者你建议怎么做?谢谢。@AlanWayne您可以在另一条记录中放入
Visit
:键入SomeType={FirstVisit:Visit;OtherInfo:OtherInfo}
。仅仅对数据进行分组,接口就显得非常重要。
{ new IVisit with
member x.first = "Yadda"
member x.last = "Yadda" }
let context = Wsdl1.GetBasicHttpBinding_IMedicalService()
let GetScheduleAsync (tableDate : DateTime) =
async {
let data = context.GetOfficeScheduleAsync(tableDate) |> Async.AwaitTask
return data |> Seq.map(fun q ->
{ new IVisit with
member this.mi = "??"
member this.lastname = q.lastname
member this.firstname = q.firstname
member this.birthdate = q.birthdate
member this.appointmentTime = q.appointment_time
member this.tservice = q.service_time
member this.postingTime = q.posting_time
member this.chartNumber = q.chart_number })
}
|> Async.StartAsTask