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



给定以下c#中的CRTP类型:

public abstract class DataProviderBase<TProvider>
    where TProvider : DataProviderBase<TProvider> { }

如何在f#中获得它的泛型类型定义?

let typeDef = typedefof<DataProviderBase<_>>

产生错误:

对类型推断变量应用默认类型'DataProviderBase<'a>'时,类型约束不匹配。当统一" a "one_answers" DataProviderBase<'a> "时,结果类型将是无限的,请考虑添加进一步的类型约束

在c#中应该是:

var typeDef = typeof(DataProviderBase<>);

更新

我找到了一个解决方法:

[<AbstractClass>]
type DummyProvider() =
  inherit DataProviderBase<DummyProvider>()
let typeDef = typeof<DummyProvider>.BaseType.GetGenericTypeDefinition()

有没有另一种不需要额外类型的方法?

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

let typeDef = typedefof<DataProviderBase<DummyProvider>>

技术细节

问题在于f#的typedefof<'T>只是一个接受类型参数的普通函数(不像c#中的typeof,它是一个操作符)。为了调用它,您需要给它一个实际的类型,然后函数将在掩护下调用GetGenericTypeDefinition

typedefof<option<_>>工作的原因是f#指定了一个默认类型作为参数(在本例中为obj)。一般来说,f#选择匹配约束的不太具体的类型。在你的例子中:

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

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

相关内容

  • 没有找到相关文章

最新更新