type FooBar = FooBar with
static member print (a:FooBar) = printfn "%s" "foobar"
type PrintDefault = PrintDefault with
static member inline print (a:int) = printfn "%s" "int"
static member inline print (a:string) = printfn "%s" "string"
static member inline print (a:obj) = printfn "%s" "object" // override others ?
let inline printOrDefault (a:^a, b:^b) =
((^a or ^b):(static member print: ^a -> unit) a)
let inline print a =
printOrDefault (a, PrintDefault)
print 42
print "hello"
print FooBar
print (box 42)
选择方法不遵循最狭窄的原则吗?但是print : obj -> unit
方法覆盖了其他方法。
public static void print<a>(a a)
{
"Dynamic invocation of print is not supported";
throw new NotSupportedException();
}
如果我不提供obj print
,c#
方法调用将获得NotSupportedException
,如果我提供obj print
,则f#中的行为会混乱。
这里选择校长的方法是什么?
超越c#interop,如果通过printOrDefault
而非print
调用,则事情是正确的。
print 42 // "object"
print "hello" // "object"
print FooBar // "object"
print (box 42) // "object"
printfn "----------------------------"
printOrDefault (42, PrintDefault) // "int"
printOrDefault ("hello", PrintDefault) // "string"
printOrDefault (FooBar, PrintDefault) // "foobar"
printOrDefault (box 42, PrintDefault) // "object"