很奇怪!尝试添加时,我的列表返回ArgumentOutofRangeException

时间:2019-03-28 21:31:22

标签: c# list add

我正在为程序执行任务列表,因此我启动了List对象。 此列表是另一类的列表,该列表具有根据类型(整数)执行的操作(任务)的信息。 在Host vs Client的讨论中,他们两个都有类(有点不同,只是我对类型的理解(客户端任务类型0!=主机任务类型0))并且我的主机列表运行良好,但是客户端没有

当尝试添加(NetObject的)类时,我的NetObjects列表返回ArgumentOutOfRangeException(我将保留示例代码)。 我不知道为什么会这样,因为列表应该是无限的,并且在添加时没有索引或其他内容(它表示索引必须为非负数并且小于集合的大小)。

这是错误:

  

ArgumentOutOfRangeException:索引超出范围。必须为非负数并且小于集合的大小。   参数名称:索引   System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument参数,System.ExceptionResource资源)(位于:0)   System.ThrowHelper.ThrowArgumentOutOfRangeException()(:0处)   System.Collections.Generic.List`1 [T] .get_Item(System.Int32索引)(在:0处)   Networking.Update()(位于Assets / Scripts / Networking.cs:225)

它说了一些我不知道为什么的get项目,因为我在代码中使用(在代码中)带有索引的任务引用(读取它),并且只有在我想添加到NetObject中时,它什么都不会发生Objects类。 我将显示主机代码,因为它可以工作,而客户端则不能,我也不会明白为什么。

我试图将锁定功能做得更好(以便没有覆盖),但从我的角度来看,除了做得更好以外,还没有做更多的事情。

这是客户端中负责执行任务的部分(在Unity中),我之所以使用任务是因为,如果不是来自主线程(并且),则Unity不允许更改游戏内容(位置,生成等)。我使用线程来接收和发送信息(在客户端和主机之间进行对话)。

for (int i = 0; i < PendingClient.Count; i++) {
            if (PendingClient[i].id > -1)
                lock (lockingClient) {
                    switch (PendingClient[i].type) {
                        case 0:
                            GameObject go = null;
                            if (GetObjectFromId(PendingClient[i].id, ref go)) {
                                go.transform.position = new Vector3(PendingClient[i].px,
                                PendingClient[i].py, PendingClient[i].pz);

                                go.transform.rotation = Quaternion.Euler(PendingClient[i].rx,
                                PendingClient[i].ry, PendingClient[i].rz);
                            } else {
                                Objects.Add(new NetObject(PendingClient[i].id,
                                PendingClient[i].objectType, PendingClient[i].name,
                                PendingHost[i].prefabName,
                                Instantiate(Resources.Load("Prefabs/" +
                                PendingClient[i].prefabName) as GameObject,
                                new Vector3(PendingClient[i].px, PendingClient[i].py,
                                PendingClient[i].pz), Quaternion.Euler(PendingClient[i].rx,
                                PendingClient[i].ry, PendingClient[i].rz))));
                            }
                            break;
                    }
                    PendingClient.RemoveAt(i);
                }
        }

错误出现在最后一个错误的下面。

以及有效的主机代码:

for (int i = 0; i < PendingHost.Count; i++) {
            lock (lockingHost) {
                if (PendingHost[i].id > -1) {
                    switch (PendingHost[i].type) {
                        case 0: // Add Object
                            Objects.Add(new NetObject(PendingHost[i].id, PendingHost[i].objectType, PendingHost[i].name, PendingHost[i].prefabName, Instantiate(Resources.Load("Prefabs/" + PendingHost[i].prefabName) as GameObject, Vector3.zero, Quaternion.identity)));
                            break;
                        case 1: // Change Transform
                            GameObject go = null;
                            GetObjectFromId(PendingHost[i].id, ref go);
                            go.transform.position = new Vector3(PendingHost[i].px, PendingHost[i].py, PendingHost[i].pz);
                            go.transform.rotation = Quaternion.Euler(PendingHost[i].rx, PendingHost[i].ry, PendingHost[i].rz);
                            break;
                    }
                    PendingHost.Remove(PendingHost[i]);
                }
            }
        }

我不是信息工程师,但我试图编写更好的代码。

感谢前进。

1 个答案:

答案 0 :(得分:4)

您致电

PendingClient.RemoveAt(i);

内部

for (int i = 0; i < PendingClient.Count; i++) {

所以i最终超出了范围。

放在一边:不要做PendingClient[i]多次,要做

var current = PendingClient[i],然后使用current