由于对象的当前状态,操作无效 - Linq on List

发布于 2024-09-27 16:36:37 字数 1285 浏览 2 评论 0 原文

对列表运行 Linq 查询时会引发此错误。

我使用 Unity3D 3.0 和 C#(Unity3D 使用 Mono 2.6)。据我所知,Unity3D是单线程的。它的工作原理是将继承基类的“脚本”(c# .cs 文件)附加到“GameObject”。此外,Unity 控制脚本的实例化和序列化,因此您不能使用构造函数。

我有一个 RoadNetwork 脚本,其中包含对 RoadNodes 和 RoadCurves 的引用,这两个脚本都通过单例定位 RoadNetwork 并自行注册/注销。我在 RoadNode 和 RoadCurve 中放置了“迷你工厂”,它们负责将自己连接到游戏对象上。

RoadNode 首先检查 RoadNetwork,以确保在同一位置不存在节点,方法如下:

public static RoadNode2 New(float x, float y, float z)
{
    //First try to find an existing one
    var rn = RoadNetwork.Instance.GetNodeAtPosition(new Vector3(x, y, z))
             ?? UnityReferenceHelper.GetNewGameObjectFor<RoadNode2>(
                 "RoadNode_" + (RoadNetwork.Instance.Nodes.Count + 1).ToString("D3"),
                 RoadNetwork.Instance.transform.FindChild("Nodes"));

    rn.Position = new Vector3(x, y, z);

    rn.gameObject.active = true;

    return rn;
}

RoadNetwork 中适当的方法是:

public RoadNode2 GetNodeAtPosition(Vector3 position)
{
    var tempList = new List<RoadNode2>();

    return tempList.Single(x => x.Position == position);
}

tempList 是缩小问题范围的尝试,但我得到了完全相同的错误。它应该是“Nodes.Single(...”,但我怀疑它是否重要。如果我直接在 New() 方法中调用 Linq 查询,我会得到同样的错误。

所以是的,这个异常抛出并指向那个 tempList .Single() 行的原因是什么?

This error is being thrown when running a Linq query over a List.

I am using Unity3D 3.0 with C# (Unity3D uses Mono 2.6). Unity3D, as far as I know, is single-threaded. It works by attaching "scripts" (c# .cs files) that inherit a baseclass, to a "GameObject". Also, Unity controls instantiation and serialization of scripts so you can't use constructors.

I have a RoadNetwork script that holds a reference to RoadNodes and RoadCurves, both of which locate RoadNetwork via a singleton and register/deregister themselves. I've put "mini-factories" in RoadNode and RoadCurve that do the hard work of hooking themselves up to a gameobject.

RoadNode first checks with RoadNetwork to make sure there isnt already a node at that same position, by doing this:

public static RoadNode2 New(float x, float y, float z)
{
    //First try to find an existing one
    var rn = RoadNetwork.Instance.GetNodeAtPosition(new Vector3(x, y, z))
             ?? UnityReferenceHelper.GetNewGameObjectFor<RoadNode2>(
                 "RoadNode_" + (RoadNetwork.Instance.Nodes.Count + 1).ToString("D3"),
                 RoadNetwork.Instance.transform.FindChild("Nodes"));

    rn.Position = new Vector3(x, y, z);

    rn.gameObject.active = true;

    return rn;
}

Where the appropriate method in RoadNetwork is:

public RoadNode2 GetNodeAtPosition(Vector3 position)
{
    var tempList = new List<RoadNode2>();

    return tempList.Single(x => x.Position == position);
}

tempList was an attempt at narrowing down the problem but I get precisely the same error. It should be "Nodes.Single(...", but I doubt it matters. I get the same error if I call the Linq query directly in the New() method.

So yes, this Exception throws and points me to that tempList.Single() line. What would the reason be?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

留一抹残留的笑 2024-10-04 16:36:37

如果 someEnumerable 中不存在一个元素,someEnumerable.Single(...) 会引发异常。鉴于您刚刚将 tempList 声明为空列表,它总是会抛出异常。

如果您想在没有元素的情况下检索 null,请使用 SingleOrDefault。 (如果枚举包含多个一个元素,这仍然会抛出异常。)如果您想要第一个元素,以便您的枚举允许包含任意数量的元素,使用 First (如果可枚举不包含元素,则抛出异常)或 FirstOrDefault (在这种情况下返回 null)。

最后,如果您只想检查列表中是否有任何元素与给定谓词匹配,请使用 Any

someEnumerable.Single(...) throws an exception if there is not exactly one element in someEnumerable. Given that you just declared tempList to be an empty list, it will always throw an exception.

If you want to retrieve null if there are no elements, use SingleOrDefault. (This will still throw an exception if the enumerable contains more than one element.) If you want the first element, so that your enumerable is allowed to contain any number of elements, use First (throws an exception if the enumerable contains no elements) or FirstOrDefault (returns null in the case).

Finally, if you want to simply check if there are any elements of a list matching a given predicate, use Any.

月亮坠入山谷 2024-10-04 16:36:37

我认为 Domenic 的意思是,只要有多个元素与您的谓词匹配,.Single() 就会抛出错误。您的集合 someEnumerable 必须包含您尝试检索的任何单例(而不是编程模式)的重复副本。

I think what Domenic meant to say was that .Single() throws an error whenever more than one element matches your predicate. Your collection someEnumerable must contain duplicate copies of whatever singleton (not the programming pattern) you're trying to retrieve.

素手挽清风 2024-10-04 16:36:37

听起来您在 Unity 中实现单例模式的方式有问题。如果您在检查列表时收到空引用异常,这意味着该列表尚未初始化,那么您可能没有实例化单例,或者没有访问您实例化的单例。

我通常使用附加到 GameObject 的单例 MonoBehaviour,在第一次访问时实例化和初始化,如下所示:

http://answers.unity3d.com/questions/156746/singleton-and-monobehaviour-in-editor.html

It sounds like there's a problem with the way you're implementing the singleton pattern in Unity. If you're getting a null reference exception when checking a list that mean the list hasn't been initialized, so you're probably either not instantiating the singleton or your not accessing the singleton you instantiated.

I usually use a singleton MonoBehaviour attached to a GameObject that instantiates and initializes on first access like this:

http://answers.unity3d.com/questions/156746/singleton-and-monobehaviour-in-editor.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文