将List <t>转换为List <object> </object> </t>

时间:2013-05-24 18:49:21

标签: c#

我的泛型类有问题。我有这样的事情:

public abstract class IGroup<T> : IEnumerable where T : class {

    protected List<T> groupMembers;
    protected List<IGameAction> groupIGameActionList;

    public IGroup() {
        groupMembers = new List<T>();

        groupIGameActionList = new List<IGameAction>();
        //groupIGameActionList.Add(new DieGameAction(groupMembers));
    }
}

第二节课:

class DieGameAction : IGameAction {

    List<object> gameObjectList;

    public DieGameAction(List<object> objectList) {
        gameObjectList = objectList; 
    }
}

我不知道如何在注释行中转换或转换groupMembers。这不起作用,因为它无法转换(List<T>List<object>)。那我怎么能这样做呢?

4 个答案:

答案 0 :(得分:30)

groupMembers.Cast<object>().ToList();

但这看起来不是一件好事。您正在创建一个与原始列表无关的新空列表。

你将使用这些课程的方式将告诉你这是不是一个好主意。 如果您计划通过向单个类添加项目来更新这两个列表,则它将不适合。那么也许您的DieGameAction也应该是通用的:DieGameAction<T>。 然后你可以在不进行投射的情况下给出原始列表。

但是,还有另一个危险:如果你为IGroup设置一个新列表,它将不会反映给DieGameAction。

所以,这一切都取决于你想要做什么。

答案 1 :(得分:1)

我今天遇到过类似的问题,但我直接打电话给它LINQ .ToArray()并且工作正常。应该是shorter而不是casting。  所以你可以说

groupMembers.ToArray();

答案 2 :(得分:0)

我只关注提供解决方案。 你可以让DieGameAction使用IList&lt;对象&gt;代替:

class DieGameAction : IGameAction {

    IList<object> gameObjectList;

    public DieGameAction(IList<object> objectList) {
        gameObjectList = objectList; 
    }
}

然后你可以提供一个IList&lt;对象&gt;适应任何IList的实现&lt; T&gt;。

public abstract class IGroup<T> : IEnumerable where T : class {

    protected List<T> groupMembers;
    protected List<IGameAction> groupIGameActionList;

    public IGroup() {
        groupMembers = new List<T>();

        groupIGameActionList = new List<IGameAction>();
        groupIGameActionList.Add(new DieGameAction(new ObjectListAdapter<T>(groupMembers)));
    }
}

我将尝试提供许多可能的解决方案之一,使用System.Collections.ObjectModel.Collection&lt; T>它还可以包装IList&lt; T&gt;:

public class ObjectListAdapter<T> : System.Collections.ObjectModel.Collection<T>, IList<object>
{
    public ObjectListAdapter(IList<T> wrappedList)
        : base(wrappedList)
    {
    }

    public int IndexOf(object item)
    {
        return base.IndexOf((T)item);
    }

    public void Insert(int index, object item)
    {
        base.Insert(index, (T)item);
    }

    public new object this[int index]
    {
        get
        {
            return base[index];
        }
        set
        {
            base[index] = (T)value;
        }
    }

    public void Add(object item)
    {
        base.Add((T)item);
    }

    public bool Contains(object item)
    {
        return base.Contains((T)item);
    }

    public void CopyTo(object[] array, int arrayIndex)
    {
        this.Cast<object>().ToArray().CopyTo(array, arrayIndex);
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(object item)
    {
        return base.Remove((T)item);
    }

    public new IEnumerator<object> GetEnumerator()
    {
        return this.Cast<object>().GetEnumerator();
    }
}

列表更改会在尝试使用不受支持的对象时抛出类型转换异常,就像我在这里编程一样,但您也可以根据需要处理它。

现在,对于IList&lt;对象&gt;您也可以尝试使用IList,而这也是由List&lt; T>所以你基本上不得不做任何其他工作。

请注意,重要的是列表在两个使用的位置都会显示相同,因为它们基本上会使用相同的底层List对象。

让我知道这是否能回答你的问题,将其标记为答案,或者不要克制:)

答案 3 :(得分:0)

老问题,但通过声明为 IList 而不是 List<object>,您可以将任何类型的列表(或数组)分配给变量,然后简单地将其强制转换为 List<Whatever>(当然,如果你将它转换为错误的类型,它会抛出异常)。