簡體   English   中英

為什么我不能通過 IList<childtype> 到 F(IEnumerable<parenttype> )?</parenttype></childtype>

[英]Why can't I pass IList<ChildType> to F(IEnumerable<ParentType>)?

我想我可以將IList<ChildClass>作為IEnumerable<ParentClass>傳遞,因為顯然 ChildType 列表中的每個 object 也是 ParentType 的實例。 但我對編譯器沒有興趣。 我錯過了什么?

編輯:添加了我想要的 function Foo3 。 謝謝!

namespace StackOverflow
{
    public class ParentClass
    {
    }

    public class ChildClass : ParentClass
    {
    }

    public class Test
    {
        // works
        static void Foo(ParentClass bar2)
        {
        }

        // fails
        static void Foo2(IEnumerable<ParentClass> bar)
        {
        }

        // EDIT: here's the right answer, obtained from the 
        // Charlie Calvert blog post 
        static void Foo3<T>(IEnumerable<T> bar) where T : ParentClass
        {
        }

        public static void Main()
        {
            var childClassList = new List<ChildClass>();

            // this works as expected
            foreach (var obj in childClassList)
                Foo(obj);

            // this won't compile
            // Argument '1': cannot convert from 
            // 'System.Collections.Generic.List<ChildClass>' 
            // to 'System.Collections.Generic.IEnumerable<ParentClass>' 
            Foo2(childClassList);

            // EDIT: this works and is what I wanted
            Foo3(childClassList);
        }
    }
}

因為 generics 不是 co/contra 變體:

Eric Lippert 的博客對此有一篇很棒的文章。

Charlie Calvert 的另一篇文章在這里

您應該在Eric Lippert 的 Covariance and Contravariance 系列中找到您要查找的所有內容。 這是一個相當多的閱讀,但回答了(a)為什么你不能在 C# 3.0 中做到這一點,以及(b)為什么你能夠在 C# 4.0 中做到這一點。

恐怕沒有對泛型參數類型的隱式轉換(沒有“泛型方差”似乎是技術術語)。 不確定我能否給你更深入的解釋,但我會接受它作為 CLR 的工作方式......

您只需使用 childClassList 上的Cast擴展方法將列表轉換為 IEnumerable。

雖然在 IList 和 IEnumerable 的情況下一切正常,但當您將其視為集合和集合時,編譯器無法真正知道這一點。

如果您可以將集合用作集合,則有人可以嘗試將 Parent 添加到集合中……編譯器必須防止這種情況發生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM