如何获取 CRTP 类型的通用类型定义
给定 C# 中的以下 CRTP 类型:
public abstract class DataProviderBase<TProvider>
where TProvider : DataProviderBase<TProvider> { }
如何在 F# 中获取其泛型类型定义?
let typeDef = typedefof<DataProviderBase<_>>
产生错误:
应用默认类型“DataProviderBase<'a>”时类型约束不匹配对于类型推断变量。当统一 ''a' 和 'DataProviderBase<'a>' 时,结果类型将是无限的考虑添加更多类型约束
在 C# 中,这将是:
var typeDef = typeof(DataProviderBase<>);
更新
我找到了一个解决方法:
[<AbstractClass>]
type DummyProvider() =
inherit DataProviderBase<DummyProvider>()
let typeDef = typeof<DummyProvider>.BaseType.GetGenericTypeDefinition()
是否有另一种方法可以做到这一点,而不需要额外的类型?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我觉得这其实是一个非常好的问题。我没有找到更好的解决方法。
您可以使用
typedefof
稍微简化您的解决方法,如下所示:技术细节
问题在于 F# 的
typedefof<'T>
只是一个普通函数它接受一个类型参数(与 C# 中的typeof
不同,它是一个运算符)。为了调用它,您需要给它一个实际类型,然后该函数将在幕后调用GetGenericTypeDefinition
。typedefof
起作用的原因是 F# 指定一个默认类型作为参数(在本例中是obj
)。一般来说,F# 选择与约束匹配的不太具体的类型。在您的情况下:DataProviderBase<_>
将变为DataProviderBase>
等等。除非您定义新类型(如解决方法中所示),否则没有具体类型可以用作
typedefof<...>
的类型参数。在这种情况下,默认机制根本不起作用......I think this is actually a very good question. I didn't find a better workaround for this.
You can slightly simplify your workaround by using
typedefof
like this:TECHNICAL DETAILS
The problem is that F#'s
typedefof<'T>
is just an ordinary function that takes a type argument (unliketypeof
in C#, which is an operator). In order to call it, you need to give it an actual type and the function will then callGetGenericTypeDefinition
under the cover.The reason why
typedefof<option<_>>
works is that F# specifies a default type as an argument (in this caseobj
). In general, F# chooses the less concrete type that matches the constraints. In your case:DataProviderBase<_>
will becomeDataProviderBase<DataProviderBase<_>>
and so on.Unless you define a new type (as in your workaround), there is no concrete type that could be used as a type argument of
typedefof<...>
. In this case, the defaulting mechanism simply doesn't work...