使用约束泛型将子类型集合作为基类型的集合返回。编译器无法推断,为什么?

时间:2018-05-16 13:32:14

标签: c# .net generics

所以我遇到了一个问题,编译器告诉我,我不能做一些我认为我应该做的事情。我已将其简化,代码位于

之下
class Program
{
    static IEnumerable<BaseInterface> GetSubInterfaceImplementers<T>()
        where T : BaseInterface
    {
        return GetThings().OfType<T>();
    }

    private static IEnumerable<BaseInterface> GetThings()
    {
        return Enumerable.Empty<BaseInterface>();
    }
}

public interface BaseInterface { }

public interface SubInterface1 : BaseInterface { }

public interface SubInterface2 : BaseInterface{ }

所以这一行return GetThings().OfType<T>();给了我这个错误:

  

无法隐式转换类型&#39; System.Collections.Generic.IEnumerable&lt; T&gt;&#39; to&#39; System.Collections.Generic.IEnumerable&lt; StackOverflowQuestions.BaseInterface&gt;&#39;。存在显式转换(您是否错过了演员?)

简而言之,即使我明确表示T必须是Type BaseInterface,它仍然无法将IEnumerable<T>强制转换为IEnumerable<BaseInterface>

如果在该方法中,我将代码改为像这样读取

return GetThings().OfType<SubInterface1>();

它编译因此显然没有问题返回子类型,这要归功于IEnumerable是&#39; Co&#39;或者&#39; Contra&#39;变种(我永远不会记得)。

那么为什么不编译?

明确的投射作品,如下:

return (IEnumerable<BaseInterface>)GetThings().OfType<T>();

但为什么编译器无法推断它

1 个答案:

答案 0 :(得分:2)

协方差仅适用于参考类型。

您的通用约束还必须指定T是引用类型(类)

static IEnumerable<BaseInterface> GetSubInterfaceImplementers<T>()
        where T : class, BaseInterface
{
        return new GetThings().OfType<T>();
}