C# 为什么不是';当作为泛型参数传递时,是否将泛型类型识别为其派生类型?

C# 为什么不是';当作为泛型参数传递时,是否将泛型类型识别为其派生类型?,c#,generics,C#,Generics,我很难理解在以下代码场景中,泛型参数应该如何工作: class Predicate { } class BarPredicate : Predicate { } class FooPredicate : Predicate { } class Program { private static IPredicateHandler<T> Create<T>(T t) where T : Predicate { // T is always

我很难理解在以下代码场景中,泛型参数应该如何工作:

class Predicate { }
class BarPredicate : Predicate { }
class FooPredicate : Predicate { }

class Program {

    private static IPredicateHandler<T> Create<T>(T t) where T : Predicate
    {
        // T is always Predicate
    } 

    static void Main(string[] args)
    {
        var list = new List<Predicate>() {new FooPredicate(), new BarPredicate()};
        foreach (var item in list)
        {
            var o = Create(item);
        }
    }
}
类谓词{}
类BarPredicate:谓词{}
类谓词:谓词{}
班级计划{
私有静态IPredicateHandler创建(T),其中T:谓词
{
//T总是谓词
} 
静态void Main(字符串[]参数)
{
var list=new list(){new foodpredicate(),new BarPredicate()};
foreach(列表中的变量项)
{
var o=创建(项目);
}
}
}

调用Create时,泛型类型T总是设置为Predicate,而不是派生类型。我理解这是因为列表中的对象存储为谓词。但是,我希望在调用Create时可以识别派生类型。为什么这里不发生这种事?是否有任何方法可以将派生类型(foodpredicate/BarPredicate)传递到Create而不是基类型(Predicate)?

这是因为您有一个
谓词列表。当您从列表中获取元素时,它仍然只是一个基类。在运行时,它将是一个派生类,但泛型在编译过程中起作用。

这是因为您有一个
谓词列表。当您从列表中获取元素时,它仍然只是一个基类。在运行时,它将是一个派生类,但泛型在编译过程中起作用。

使用动态类型执行重载解析的最简单方法是使用
dynamic
关键字

foreach (dynamic item in list) {
    dynamic o = Create(item);
}

使用动态类型执行重载解析的最简单方法是使用
dynamic
关键字

foreach (dynamic item in list) {
    dynamic o = Create(item);
}

+1.而且它确实创建了正确的类型-谢谢!(比
MakeGenericType
code简单多了)。同意。这是一个妙计。试图弄清楚它到底是如何(以及为什么)工作的@j0k:之所以有效,是因为
dynamic
意味着“在运行时再次启动编译器并重新分析此表达式,就像运行时类型是原始表达式中给定给编译器的类型一样”。是的,它的速度和听起来一样快。而且它确实创建了正确的类型-谢谢!(比
MakeGenericType
code简单多了)。同意。这是一个妙计。试图弄清楚它到底是如何(以及为什么)工作的@j0k:之所以有效,是因为
dynamic
意味着“在运行时再次启动编译器并重新分析此表达式,就像运行时类型是原始表达式中给定给编译器的类型一样”。是的,它的速度和听起来一样快。我知道,但我没有想到。谢谢你的提醒!我知道,但没想到。谢谢你的提醒!