Dax*_*ohl 10 f# type-providers
我想要一些方法来定义相关记录.例如,
type Thing = { field1: string; field2: float }
type ThingRecord = { field1: string; field2: float; id: int; created: DateTime }
Run Code Online (Sandbox Code Playgroud)
要么
type UserProfile = { username: string; name: string; address: string }
type NewUserReq = { username: string; name: string; address: string; password: string }
type UserRecord = { username: string; name: string; address: string; encryptedPwd: string; salt: string }
Run Code Online (Sandbox Code Playgroud)
以及从一个转换到另一个的方式,而不需要写那么多样板文件.即使是第一个完整的例子也是:
type Thing =
{ field1: string
field2: float }
with
member this.toThingRecord(id, created) =
{ field1 = this.field1
field2 = this.field2
id = id
created = created } : ThingRecord
and ThingRecord =
{ field1: string
field2: float
id: int
created: DateTime }
with
member this.toThing() =
{ field1 = this.field1
field2 = this.field2 } : Thing
Run Code Online (Sandbox Code Playgroud)
当你起床field10等时,它将成为一种负担.
我目前使用反射以不安全(和缓慢)的方式执行此操作.
我添加了一个with语法请求,以扩展到uservoice上的记录定义,这将满足这一需求.
但是,是否有一种类型安全的方法可以做到这一点?也许与类型提供商?
是的,这是F#否则有光泽的装甲的缺点。我觉得没有一个通用的解决方案可以轻松地继承或扩展记录。毫无疑问,是一个胃口-我数了崇尚沿着这些路线的改进十几UserVoice的提交-这里有几个领头的人,随意投票了:1,2,3,4,5。
当然,您可以采取一些措施来解决此问题,并且根据您的情况,它们可能对您很有用。但最终-它们是解决方法,您必须牺牲一些东西:
类型提供者不会削减它,因为它们并不是元编程真正的好工具。那不是他们设计的目的。如果尝试以这种方式使用它们,那么必然会遇到一些限制。
首先,您只能提供基于外部信息的类型。这意味着,尽管您可以使用类型提供程序通过反射从.NET程序集中提取类型并提供一些基于该类型的派生类型,但您不能“全面了解”正在构建的程序集。因此,无法从同一程序集中先前定义的类型派生任何方法。
我想您可以通过围绕类型提供程序构建项目来解决此问题,但这听起来很笨拙。即使如此,你不能提供记录类型反正还没有,所以最好你可以做的是纯.NET类。
对于为数据库提供某种ORM映射的更特定的用例,我想您可以使用类型提供程序就好了。只是不作为通用元编程工具。