当类型已知时,类型“T”不能用作泛型类型中的类型参数或方法错误

Posted

技术标签:

【中文标题】当类型已知时,类型“T”不能用作泛型类型中的类型参数或方法错误【英文标题】:The type 'T' cannot be used as type parameter in the generic type or method error when type is known 【发布时间】:2012-11-06 14:41:00 【问题描述】:

考虑以下代码示例,其中Concrete 派生自Base

class Base
class Concrete : Base 

static void Foo<T>() where T : Base

    if (typeof(Concrete).IsAssignableFrom(typeof(T)))
    
        var x = new Bar<T>(); // compile error on this line
    


class Bar<T> where T : Concrete


在我遇到编译错误的那一行,我已经检查了泛型参数是否可以分配给Concrete 类型。所以理论上我相信应该有一种方法可以创建 Bar 类的实例。

有什么办法可以消除编译错误?我想不出一种方法来提出论点。


编译错误全文:

错误 14 类型 'T' 不能用作类型参数 'T' 在 泛型类型或方法 '酒吧'。那里 没有从 'T' 到的隐式引用转换 “具体”。

【问题讨论】:

为我编译...是 actual 示例吗?你的真实代码中可能有参数吗? 您的代码与错误消息不匹配。你肯定写了Bar&lt;T&gt;(); Foo没有where T : Concrete有什么原因吗? 在编辑时,您可能还想澄清BaseConcrete之间的关系 @ZaidMasud 谢谢;通过该编辑:没有常规的方法可以做到这一点。你可以用反射(MakeGenericMethod 等)破解它,但这不是一个的答案。如果您可以从Bar&lt;T&gt; 中删除约束并在Bar&lt;T&gt; 内进行一些转换(通过object), 可能会起作用。 【参考方案1】:

编译器无法知道当前对 Base 的约束的 T 实际上是 Concrete,即使您之前对其进行了测试。

所以:

Type type = typeof(Bar<>);
Type generic = type.MakeGenericType(typeof(T));
var x = Activator.CreateInstance(generic); 

不要让它有机会这样做。

【讨论】:

以上是关于当类型已知时,类型“T”不能用作泛型类型中的类型参数或方法错误的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 泛型 Array<T> 导致“不能将 T 用作具体类型参数。请改用类”但 List<T> 不会

默认泛型可作为参数正常使用,但不能作为函数参数的返回类型使用

“T”必须是具有公共的无参数构造函数的非抽象类型,才能用作泛型类型或方法

为 T 已知运行时反射地创建 Seq[T]

将泛型 T 的类型解析为 C# 中的特定接口

days14--泛型