有没有办法将System.Type转换为实现接口(包括new())?

Is there a way to cast a System.Type as implementing interfaces (including new())?

提问人:riizade 提问时间:7/27/2022 更新时间:7/28/2022 访问量:36

问:

我有以下两个方法定义:

  • static T DeserializeNormal<T>(string s)
  • static T DeserializeSpecial<T>(string s) where T: IMessage<T>, new()

我想编写一个具有以下签名的方法static T Deserialize<T>(string s)

新方法将简单地检查 T 是否实现了 和 ,如果是,则调用 ,如果没有,则调用 。IMessage<T>new()DeserializeSpecial<T>()DeserializeNormal<T>()

我遇到了两个问题:

  1. 有没有办法检查一个工具?我似乎无法通过该模式实现这一点,因为实际上不是一个接口。System.Typenew()(System.Type)typeof(T).GetInterfaces().GetValue(0) == typeof(IMessage);new()
  2. 有没有办法强制转换为编译器,它实际上实现了 和 ?就目前而言,我可以检查 ,但是然后尝试调用会给我一个编译器错误,该错误无法实现,即使我刚刚检查了。我能找到的所有强制转换行为都是针对对象的,而不是.typeof(T)IMessage<T>new()IMessageDeserializeSpecial<T>()TIMessageSystem.Type
C# 类型 接口 转换

评论

1赞 Chetan 7/27/2022
您无需检查 .如果使用的类型没有无参数构造函数,编译器将显示错误。new()
0赞 riizade 7/27/2022
由于函数的类型参数是泛型的,因此编译器无法知道类型是否具有无参数构造函数,因为类型参数在运行时之前没有值。
0赞 David L 7/27/2022
你把意图混为一谈。如果你使用的是泛型,编译器会给你保证,正如 Chetan 指出的那样。通常,如果您没有强类型化方法调用,则只需要检查 Type 中是否有无参数构造函数之类的内容。
0赞 David L 7/27/2022
@riizade,这完全是不正确的。
0赞 Chetan 7/27/2022
编译时的类型检查是泛型和约束的目的。dotnetfiddle.net/AzoSkGwhere

答:

0赞 David L 7/28/2022 #1

根据您的澄清评论,我相信您要完成的是,您希望能够在运行时检查类型是否具有无参数构造函数,模拟与约束相同的行为。where new()

显然,如果在运行时完成,效率要低得多,但您绝对可以检查无参数构造函数。

if (typeof(T).GetConstructor(Type.EmptyTypes) is not null)
{
    // call method 
}

这当然会产生其他问题,例如,如果该类型尚不存在,则可能需要动态创建该类型,并且它会阻止您在没有额外反射的情况下进行调用。DeserializeSpecial<T>