2017-05-24 57 views
2

我得到的ToBar为什么这个代码不够通用甚至更好为什么甚至检查?

type Foo = {foo: string} 
type Bar = {bar: string} 

[<AbstractClass>] 
type AbstractType< ^T> (fn: ^T -> Foo) = 

    member inline this.ToFoo (x: ^T) = fn x 
    abstract ToBar: string -> Bar 

这定义的错误是错误消息

This code is not sufficiently generic. 
The type variable ^T could not be generalized 
because it would escape its scope. 
从事实

除了那个(甚至是阅读所有其他等等这个问题之后)我不知道得到什么这个错误试图告诉我...但它是完全惊人的ToBar甚至不使用该类型的参数正在出现错误

回答

4

这是因为ToBar不是inline,这是使用静态解析类型约束的必要条件。但似乎你并不真的需要它们,简单的泛型就足够了。所以只是'T取代^T,这将很好地工作:

[<AbstractClass>] 
type AbstractType<'T> (fn: 'T -> Foo) = 

    member inline this.ToFoo (x: 'T) = fn x 
    abstract ToBar: string -> Bar 

如果你想多一点,它才有意义:一个abstract成员不能很好的运用SRTC的,因为它是在派遣运行时和SRTC类型需要在编译时知道。

与此相关的,即使你在努力保持SRTC摆脱ToBar,你会打一个错误:

error FS1113: The value 'ToFoo' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible 

这可以通过类型本身的私人固定:

type private AbstractType< ^T> (fn: ^T -> Foo) = 
    member inline this.ToFoo (x: ^T) = fn x 

这将起作用,因为该类型不能从外部程序集访问,因此不需要公开其SRTC参数。

相关问题