有没有办法以某种方式重载函数?
我们来看看这3个功能:
// Returns StringPropertyInfo
let stringProperty (expr:Expr<'a -> string>) (cfg:EntityInfo<'a>) =
cfg.Property expr
// Returns DatePropertyInfo
let dateProperty (expr:Expr<'a -> System.DateTime>) (cfg:EntityInfo<'a>) =
cfg.Property expr
// Returns BytePropertyInfo
let byteProperty (expr:Expr<'a -> System.Byte>) (cfg:EntityInfo<'a>) =
cfg.Property expr
Run Code Online (Sandbox Code Playgroud)
有没有办法将它们全部合并到:
let property expr cfg = ....
Run Code Online (Sandbox Code Playgroud)
如果没有,最简洁的方法是什么类似的?
Tom*_*cek 14
如果你想使用基于有区别的联合的方法,那么我认为声明更合适(因为你不需要用引号来操作).Alex建议的类型的轻微修改是:
type PropertyInfo<'a> =
| String of Expr<'a -> string>
| Date of Expr<'a -> System.DateTime>
| ...
Run Code Online (Sandbox Code Playgroud)
那你就写下这样的东西:
let property (pi:PropertyInfo<'a>) (cfg:EntityInfo<'a>) =
match pi with
| String e -> cfg.Property e
| ...
cfg |> property (String <@ fun e -> e.Foo @>)
Run Code Online (Sandbox Code Playgroud)
另一种选择是实现property
作为类型的静态成员,在这种情况下,您可以使用通常的重载(类似于C#).就像是:
type EF =
static member property (expr:Expr<'a -> string>) (cfg:EntityInfo<'a>) =
cfg.Property expr
static member property (expr:Expr<'a -> System.DateTime>) (cfg:EntityInfo<'a>) =
cfg.Property expr
static member property (expr:Expr<'a -> System.Byte>) (cfg:EntityInfo<'a>) =
cfg.Property expr
Run Code Online (Sandbox Code Playgroud)
然后你会写:
cfg |> EF.property <@ e -> e.Foo @>
Run Code Online (Sandbox Code Playgroud)
最后,通过使函数完全通用并进行动态类型测试(以确定使用的返回类型),您还可以使它更简单(但不那么安全).就像是:
let property<'a, 'r> (e:Expr<'a -> 'r>) (cfg:EntityInfo<'a>) =
if typeof<'r> = typeof<string> then
// ...
Run Code Online (Sandbox Code Playgroud)
我认为在这种情况下,受歧视的工会是你的朋友,你会有类似的东西
type PropertyInfo =
| StringPropertyInfo of string
| DatePropertyInfo of System.DateTime
| BytePropertyInfo of byte
Run Code Online (Sandbox Code Playgroud)
然后匹配它并在一个函数中执行适当的操作返回union ...