Unity “null” == 检查失败?

Unity "null" == Check Failing?

提问人:Spring E. Thing 提问时间:7/22/2023 最后编辑:Spring E. Thing 更新时间:7/25/2023 访问量:105

问:

https://i.stack.imgur.com/jyYpi.gif所以我做 Unity C# 编程已经有大约 6 年了,我只是刚刚发现 C# 与 s.Unity(我猜这就是你学习 C# 的方式时得到的)。毋庸置疑,这项工作相当麻烦,因为多年来我一直在项目中使用运算符吨,由于 Unity 是用 C++ 编写的,而 C# 只是编写项目的层,因此根本无法与 Unity 一起使用,Unity AFAIK 的真正含义是被销毁,但引用仍然存在用于调试目的,只有在 GC 之后才会成为 C#。null"null"?."null""null"UnityEngine.Objectnull

我已经对 Unity 和 C# 之间的差异进行了一些研究,我对为什么我仍然遇到空检查问题感到非常困惑。 您可以在上面的GIF中看到,这显然是Unity而不是C#。我做了一个比较,从我被告知应该在这种情况下,因为 Unity 覆盖了所有实例的运算符并考虑了这一点,而不是不考虑类似 .但是,正如您在 GIF 中也可以看到的,存储此比较结果(用于调试目的)的是 ,这让我感到困惑,我明确使用了我被告知在这种情况下覆盖的运算符,但我得到了相同的结果,就好像我没有明确比较一样。"null"nullinst"null"nullinst==nulltrue==UnityEngine.Object?.bool==false==UnityEngine.Object

请注意有关所提供的 GIF 的一些事项:

  1. GIF中的某些功能不必要地冗长,以帮助我调试此问题
  2. TRefType被收缩为 a ,所以它可以是 an 或 a,我需要一种方法来检查其中任何一个。whereclassobjectUnityEngine.Objectnull

这是怎么回事?!整个 C# 与光是 Unity 这件事就打乱了我的流程,现在我对这个问题的理解可能也不完全存在! 有关整个主题的更多信息,假设您像我发现 Unity 时一样迷茫,请查看以下内容: https://blog.unity.com/technology/custom-operator-should-we-keep-itnull"null""null"

以下是我在写这篇文章之前检查的其他一些 StackOverflow 线程,它们只会进一步说服我我目前的理解是正确的,但我仍然没有得到我期望的结果: 为什么 C# null 条件运算符不适用于 Unity 可序列化变量? Unity : this == null 返回 true。怎么会这样呢?

这是我在项目的其余部分独立使用的函数,作为代码块,以方便您回复。您可以忽略其他结果,它们现在正在按预期运行:case

        private bool IsNull(TRefType inst)
        {
            Type instType = null;

            if(inst!=null)
                instType = inst.GetType();

            switch (instType)
            {
                case Type t when t == typeof(string):
                    return string.IsNullOrWhiteSpace(inst.ToString());
                case Type t when t == typeof(IEnumerable):
                    if (t != typeof(IDictionary))
                        return CollectionHelpers.AnyAllScanners.AnyElementsNotNull(inst as IEnumerable);
                    else
                        return CollectionHelpers.AnyAllScanners.AnyElementsNotNull(inst as IDictionary);
                default:
                    bool iN = inst==null;
                    bool iTN = instType == null;
                    return iN || iTN;
            }
        }

任何帮助,非常感谢!

C# unity-game-engine 对象 null 检查

评论


答:

1赞 Guru Stron 7/22/2023 #1

这似乎是某个泛型类的一部分,对于用作泛型类型参数的所有引用类型,泛型方法实现将被共享(即编译器将为作为泛型类型参数传递的所有引用类型生成一个方法,以防止代码膨胀),因此运算符解析发生在编译时,因此在这种情况下,这是“C# 的 null”。IsNull

您添加检查:UnityEngine.Object

switch (instType)
{
    // ...
    case _ when typeof(UnityEngine.Object).IsAssignableFrom(instType):
        return (inst as UnityEngine.Object) == null; 
    // ...
}

评论

0赞 Spring E. Thing 7/22/2023
TYSM回复我!最后几分钟我开始有同样的感觉,这个答案似乎很有希望,并为我澄清了一些琐碎的事情,但现在我遇到了一个问题,因为被收缩到 ,所以没有从 到 的演员。为了仅成为引用类型,我是否可以收缩其他内容?files.catbox.moe/w4av1b.pngTRefTypewhereclassTRefTypeUnityEngine.ObjectTRefType
0赞 Guru Stron 7/22/2023
@SpringE.Thing 已经很久没有使用 Unity 了,目前没有设置,请尝试或((UnityEngine.Object)(object)inst)(inst as UnityEngine.Object)
0赞 Spring E. Thing 7/22/2023
我尝试了第二种选择,即使有限制也是可以编译的,这给了我很好的感觉,因为你对我的回答的逻辑是合理的,但可悲的是,即便如此,它也没有认识到这是一个,或者至少是从它衍生出来的,我真的不明白,我希望它至少会选择正确的。files.catbox.moe/rixz3s.pngwhereinstUnityEngine.ObjectinstUnityEngine.GameObjectcase
1赞 Spring E. Thing 7/22/2023
这成功了,非常感谢!你不知道我在这个概念上浪费了多少个工作之夜,我更感激你给出的答案是如此清晰易懂。毕竟,这不是我误解了,只是假设的通用性质使用错误,我需要明确说明正在处理的类型。==overrideclass==override
1赞 Spring E. Thing 7/22/2023
做!又是TY了!: )