2

例子:

        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'”

我怎样才能解决这个问题?谢谢。

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

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

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

我知道

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

总是工作。只是寻找更优雅的东西。

4

4 回答 4

6

我怎样才能解决这个问题?

改变你的设计。你不能沮丧 - aMyList aList<string>但反之亦然。您可以通过重新使用List<T>接受任何IEnumerable<T>(包括 a 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
}

目的是在不引入任何向后不兼容的情况下将所有转换为代码ListMyList

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

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

不能。AList<string> 不一定MyList。就像 aCat不是 a一样Tiger。它可能是,但你不能只是投射是并把它当作是。

请注意,如果您将列表创建MyList(例如List<T> newList = new MyList()),那么您可以安全地转换它。实际上,您可以在其他任何地方使用它,就好像它是 a 一样List<string>(因为它是!)但是您不能安全地将任意值强制List<string>转换为 a MyList。时期。

于 2013-08-01T21:37:51.033 回答
4

你不能做这个。考虑:

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()!
于 2013-08-01T21:34:18.873 回答
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>
    {
    }
于 2013-08-01T21:54:58.440 回答
0

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

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);
于 2013-08-01T23:22:02.020 回答