鉴于以下 CRTP输入 C#:
public abstract class DataProviderBase<TProvider>
where TProvider : DataProviderBase<TProvider> { }
我如何在 F# 中获得它的泛型类型定义?
let typeDef = typedefof<DataProviderBase<_>>
产生错误:
Type constraint mismatch when applying the default type 'DataProviderBase<'a>' for a type inference variable. The resulting type would be infinite when unifying ''a' and 'DataProviderBase<'a>' Consider adding further type constraints
在 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<...>
的类型参数。 .在这种情况下,默认机制根本不起作用......
关于reflection - 如何获取 CRTP 类型的泛型类型定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6783284/