从List <t>继承的类型不能与List <t> </t> </t>一起分配

时间:2013-08-01 21:29:40

标签: c# class generics inheritance

示例:

        public class ListInheritanceTest
        {
            public void Test1()
            {
                List<string> list = new List<string>();
                MyList myList = list;
            }
        }
        public class MyList : List<string>
        {
        }

但是MyList myList = list有错误“无法将类型'System.Collections.Generic.List'隐式转换为'ConsoleTest.MyList'”

我该如何解决这个问题?感谢。

---- ----编辑
我不是在问它为什么会出错。我想知道使分配工作的解决方法是什么。 上面的代码只是一个简化的例子。目的是在我的代码中将所有List<SomeType>转换为MyList,而不会引入任何向后不兼容。

---第二次编辑----

让我重新解释一下这个问题。假设我在上面的代码中以相同的方式定义了MyList。 List<string>分配给MyList的最简单方法是什么。

我知道

            foreach(var item in list)  
            mylist.Add(item)  

始终有效。只是寻找更优雅的东西。

4 个答案:

答案 0 :(得分:5)

  

我该如何解决这个问题?

更改您的设计。您无法向下转发 - MyList List<string>但反之亦然。您可以通过重复使用接受任何List<T>的{​​{1}}副本构造函数(包括IEnumerable<T>)将项目复制到新列表中:

List<string>
  

目的是在代码中将所有public class ListInheritanceTest { public void Test1() { List<string> list = new List<string>(); MyList myList = new MyList(list); // copy the items in the list } } public class MyList : List<string> { public MyList(IEnumerable<string> list) : base(list) {} // reuse the List<T> copy constructor } 转换为List,而不会引入任何向后不兼容。

再一次,你不能。 MyList不是List。您可以做的最好的事情是使用复制构造函数或其他方法列表转换为MyList

  

MyList分配给List<string>的最简单方法是什么。

不能MyList 不一定是 List<string>。与MyList不是Cat的方式相同。它可能是,但你不能只是施放并将它视为它。

请注意,如果您创建列表为Tiger(例如MyList),那么您可以安全地投射它。事实上,你可以在其他地方使用它,好像它是List<T> newList = new MyList()(因为它是!)但你无法安全地将List<string>强制转换为List<string>。周期。

答案 1 :(得分:3)

你不能这样做。考虑:

public class MyList : List<string>
{
    public string DoSomething()
    {
        return "Something";
    }
}

//...

List<string> l = new List<string>();
((MyList)l).DoSomething(); // ERROR - List<string> does not define DoSomething()!

答案 2 :(得分:1)

我认为这解决了这个问题,并允许添加任何列表之王(字符串,整数,......):

    public class ListInheritanceTest
    {
        public void Test1()
        {
            List<string> list = new List<string>() { "1", "2", "3", "4", "5" };

            MyList<string> myList = new MyList<string>();
            myList.AddRange(list);

            foreach (var item in myList)
            {
                Console.WriteLine(item);
            }
        }
    }
    public class MyList<T> : List<T>
    {
    }

另一种方式,因为MyList是从List派生的(这适用于某些特定情况,对于上面这个例子更好):

    public class ListInheritanceTest
    {
        public void Test1()
        {
            List<string> list = new MyList<string> { "1", "2", "3", "4", "5" };

            MyList<string> myList = (MyList<string>) list;


            foreach (var item in myList)
            {
                Console.WriteLine(item);
            }
        }
    }
    public class MyList<T> : List<T>
    {
    }

答案 3 :(得分:0)

如果要避免复制列表,则必须稍微更改MyList。这将允许您随时包装List并具有相同的界面,而无需复制元素。

class MyList : IList<string>
{
    private readonly List<string> theList;

    public MyList(List<string> list)
    {
        theList = list;
    }

    // Implement the IList<string> interface by
    // calling the same methods on theList
}

List<string> oldList = new List<string>();
MyList wrapper = new MyList(oldList);