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

标签 reflection f# crtp

鉴于以下 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/

相关文章:

java - 使用 Proguard 后通过反射访问方法时出现 NoSuchMethodException

java - 在 Java 中,给定一个对象,是否可以覆盖其中一个方法?

wcf - 如何在.NET Core 3.1中从F#访问WCF服务?

用于转发协变返回的 C++ 抽象基础模板

c++ - CRTP Singleton 不完整类型或非文字类型

java - 是否可以使用反射获取包中公共(public)接口(interface)和类的集合?

c# - 从 C# 类获取 JSON PropertyName,例如 json 属性的 "nameof(class.prop)"?

f# - 使用 F# 对可变值进行模式匹配

F# 匹配表达式和 'as' 模式

c++ - 声明一个与给定模板参数的函数具有相同签名的函数