返回带有yield return的泛型参数T.

时间:2018-04-04 04:22:43

标签: generics casting yield return-type

我想从加载的dll文件生成一个类型列表(从T类继承)。但是,当我使用以下代码时,应用程序变得冻结/卡住:

static IEnumerable<T> GetAllTypes<T>(string dllName)
{
    Assembly plugin = Assembly.LoadFrom(dllName);
    if (plugin != null)
    {
        Type[] types = plugin.GetTypes();
        foreach (var type in types)
        {
            if (type.IsClass && type.IsSubclassOf(typeof(T)))
            {
                Console.WriteLine(type.Name);
                yield return (T)(Object)type;
            }
        }
    }
    else
        throw new InvalidDataException();
}

但是,如果我不使用yield return,一切都按预期工作,不会发生冻结。任何人都可以解释这种行为吗?

static void GetAllTypes<T>(string dllName)
{
    Assembly plugin = Assembly.LoadFrom(dllName);
    if (plugin != null)
    {
        Type[] types = plugin.GetTypes();
        foreach (var type in types)
        {
            if (type.IsClass && type.IsSubclassOf(typeof(T)))
            {
                Console.WriteLine(type.Name);
                //yield return (T)(Object)type;
            }
        }
    }
    else
        throw new InvalidDataException();
}

2 个答案:

答案 0 :(得分:0)

请注意,type System.Type 的实例。你应该(yield)返回它,并使IEnumerable<System.Type>返回类型。

您的输入代码尝试将该对象转换为 T 的实例,这是无效且不可能的,它无法正常工作。类型T的对象与类型T本身不同,但这正是您的代码试图强制的。

不确定是否会挂起&#39;可能是结果,但铸造代码是错误的。

答案 1 :(得分:0)

你的应用程序可能没有卡住,问题是迭代器是 lazy 。你已经建了一个问题,但你还没有问过它。

var types = GetTypes("Foo");

这只会创建一个查询,但实际上不会执行它。这将:

foreach (var t in types) { ... }

那就是说,你的代码永远不会像其他答案中解释的那样工作。 typeof(T)T完全不同。