如何获取CRTP类型的泛型类型定义

时间:2011-07-21 21:52:19

标签: reflection f# crtp

在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()

有没有其他方法可以做到这一点,没有额外的类型?

1 个答案:

答案 0 :(得分:4)

我认为这实际上是一个非常好的问题。我没有找到更好的解决方法。 您可以使用typedefof这样稍微简化您的解决方法:

let typeDef = typedefof<DataProviderBase<DummyProvider>>

技术细节

问题是F#的typedefof<'T>只是一个带有类型参数的普通函数(与C#中的typeof不同,它是一个运算符)。为了调用它,你需要给它一个实际类型,然后函数将在封面下调用GetGenericTypeDefinition

typedefof<option<_>>工作的原因是F#指定默认类型作为参数(在本例中为obj)。通常,F#选择与约束匹配的不太具体的类型。在你的情况下:

DataProviderBase<_>将成为DataProviderBase<DataProviderBase<_>>,依此类推。

除非您定义新类型(如在变通方法中),否则没有具体类型可用作typedefof<...>的类型参数。在这种情况下,默认机制根本不起作用......