在C#中给出以下CRTP类型:
public abstract class DataProviderBase<TProvider>
where TProvider : DataProviderBase<TProvider> { }
我如何在F#中获得其泛型类型定义?
let typeDef = typedefof<DataProviderBase<_>>
产生错误:
应用默认类型'DataProviderBase&lt;'&gt;'时类型约束不匹配对于类型推理变量。统一''a'和'DataProviderBase&lt;'&gt;'时,结果类型将是无限的考虑添加更多类型约束
在C#中,它将是:
var typeDef = typeof(DataProviderBase<>);
我找到了解决方法:
[<AbstractClass>]
type DummyProvider() =
inherit DataProviderBase<DummyProvider>()
let typeDef = typeof<DummyProvider>.BaseType.GetGenericTypeDefinition()
有没有其他方法可以做到这一点,没有额外的类型?
答案 0 :(得分:4)
我认为这实际上是一个非常好的问题。我没有找到更好的解决方法。
您可以使用typedefof
这样稍微简化您的解决方法:
let typeDef = typedefof<DataProviderBase<DummyProvider>>
技术细节
问题是F#的typedefof<'T>
只是一个带有类型参数的普通函数(与C#中的typeof
不同,它是一个运算符)。为了调用它,你需要给它一个实际类型,然后函数将在封面下调用GetGenericTypeDefinition
。
typedefof<option<_>>
工作的原因是F#指定默认类型作为参数(在本例中为obj
)。通常,F#选择与约束匹配的不太具体的类型。在你的情况下:
DataProviderBase<_>
将成为DataProviderBase<DataProviderBase<_>>
,依此类推。
除非您定义新类型(如在变通方法中),否则没有具体类型可用作typedefof<...>
的类型参数。在这种情况下,默认机制根本不起作用......