28

I have a problem with the generic class. I have something like this:

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));
    }
}

And second class:

class DieGameAction : IGameAction {

    List<object> gameObjectList;

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

I don't know how to cast or convert groupMembers in commented line. This doesn't work because it can not be converted (List<T> to List<object>). So how can I do it?


Can't figure out this segfault

Trying to issue an execve() syscall in Linux to touch a file called "Everything is OK"

Here's the stack:

0xffffd33c: 0x6e69622f  0x756f742f  0x45006863  0x79726576

0xffffd34c: 0x6e696874  0x73692067  0x004b4f20  0x00000000

0xffffd35c: 0xf7ff000a  0x00000001  0x080483a0  0x00000000

0xffffd36c: 0x080483c1  0x08048454  0x00000001  0xffffd394

That should be little-endian ordered "/bin/touch\0Everything is OK\0" followed by a NULL byte, which it appears to be.

Here are the registers:

eax            0xfffffff2       -14
ecx            0xffffd33c       -11460
edx            0x0  0
ebx            0xffffd33c       -11460
esp            0xffffd33c       0xffffd33c

EAX was 11 (for execve() linux syscall) before the int 0x80 caused an error which changed the value of EAX to -14

I can't figure out why my pointers (stored in ebx, ecx) are causing a format error with execve()'s arguments. They point to the same data, but it's a null-terminated string followed by a second null terminated string followed by a NULL pointer, so it should be treated as only the first string by ebx an as a NULL pointer terminated array by ECX.

Thanks.

4

5 回答 5

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

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

您将使用这些类的方式将告诉您这是否是一个好主意。如果您打算通过将项目添加到单个类来更新两个列表,则它不适合。那么也许你DieGameAction也应该是通用的:DieGameAction<T>. 然后你可以在不强制转换的情况下给出原始列表。

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

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

于 2013-05-24T18:51:19.007 回答
1

我将只专注于提供解决方案。你可以让 DieGameAction 使用 IList < object > 代替:

class DieGameAction : IGameAction {

    IList<object> gameObjectList;

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

然后,您可以提供适应任何 IList < T > 的 IList < object > 实现。

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 < T > 作为基础,它也可以包装 IList < T >:

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 < object > 您也可以尝试使用 IList 代替,这也是由 List < T > 实现的,因此您基本上无需再做任何事情即可使其正常工作。

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

让我知道这是否回答了您的问题,将其标记为答案,或者不要避免:)

于 2015-04-04T19:00:40.750 回答
0

我今天有类似的问题,但我LINQ .ToArray()直接打电话给它,它工作正常。那应该shortercasting。所以你可以说

groupMembers.ToArray();
于 2017-07-26T10:14:58.417 回答
0

它对我有用:

List<myclass> listMyclass = new List<myclass>();
var listObject = listMyclass.ToList<object>();
于 2021-12-11T17:16:55.677 回答
0

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

于 2021-04-29T14:12:22.660 回答