首页 > 解决方案 > Rider 检查空对象的新方法

问题描述

假设我们正在 Unity 中构建一个游戏,并且我们想要检查玩家是否为空的每一帧。

我知道这不是最佳的,但我只想举一个例子来说明我的问题。

// Update is called once per frame
private void Update()
{
    if (player != null)
    {
        player.Move();
    }
}

根据 Jetbrains,我们应该避免与 UnityEngine.Object 子类进行空比较,因为这是一件非常昂贵的事情。特别是如果我们每帧都这样做(可能是每秒 100 次)。

所以我决定让 Rider 以尽可能便宜的方式检查 Player 是否为 null。Rider 决定将我的代码重构为:

// Update is called once per frame
private void Update()
{
    if (player is { } && player)
    {
        player.Move();
    }
}

我是 C# 的新手,我真的不明白为什么它不能满足以下条件:

// Update is called once per frame
private void Update()
{
    if (player)
    {
        player.Move();
    }
}

为什么 Rider 也将 Player 与一对空括号进行比较?

标签: c#unity3drider

解决方案


Rider 抱怨性能损失的原因是“UnityEngine.Object”有自己的实现operator==,这意味着它比简单的空检查更昂贵。它不会做更多的事情(因为这通常在相等操作中明确测试),但它通常至少涉及一个虚函数调用(to Equals(object))。

你的最后一个例子

// Update is called once per frame
private void Update()
{
    if (player)
    {
        player.Move();
    }
}

只是不能在 C# 中编译。C# 不提供从对 bool 的引用的隐式转换。

你真正要找的是Object.ReferenceEquals(). 此方法确保,即使运算符重载或其他任何情况,也仅完成参考比较。

所以这变为:

// Update is called once per frame
private void Update()
{
    if (!ReferenceEquals(player, null))
    {
        player.Move();
    }
}

这是一个非常快速的操作,不应给出任何警告的理由。


推荐阅读