为什么Unity3d C#中的if语句允许不是bool的对象?

4 c# unity-game-engine

在标准的.NET 4.6编译器中,以下if语句不合法,您将收到编译器错误:CS0029无法将类型'UserQuery.TestClass'隐式转换为'bool'.这一切都很好,我理解这一点.

void Main()
{
    TestClass foo = new TestClass();

    if(foo) 
    {
        "Huh. Who knew?".Dump();
    }
}


public class TestClass : Object
{
}
Run Code Online (Sandbox Code Playgroud)

但是,在Unity3d中,这段代码是完全合法的,我已经看到了几个例子,甚至鼓励这种Javascript样式的空检查.

这里发生了什么,是否可以在.NET中的非Unity3d工作中利用这一点?

以下是Unity3D中合法代码的示例:

using UnityEngine;

public class SampleIfBehavior : MonoBehaviour
{

    // Use this for initialization
    void Start ()
    {
        var obj = new SampleIfBehavior();

        if (obj)
        {
            Console.Write("It wasn't null.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

情节变粗!如果我尝试比较一个不是从单声道行为派生的对象,我会得到预期的编译器警告.

public class TestClass
{
}
void Start ()
{
    var obj2 = new TestClass();
    if (obj2) // cast from TestClass to bool compiler error
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

感谢Programmer,我一直在挖掘Unity3D的Object(我忽略了它,因为我错误地认为它是.NET的实际对象.)

好奇的相关代码(在UnityEngine.Object中):

public static implicit operator bool(Object exists)
{
  return !Object.CompareBaseObjects(exists, (Object) null);
}

public static bool operator ==(Object x, Object y)
{
  return Object.CompareBaseObjects(x, y);
}

public static bool operator !=(Object x, Object y)
{
  return !Object.CompareBaseObjects(x, y);
}
Run Code Online (Sandbox Code Playgroud)

Pro*_*mer 12

不要太担心这个.这if (obj)在Unity中是合法的,因为Unity中存在隐式运算符重载.我相信这是在做MonoBehaviour或UnityEngine.Object类.

它看起来像这样:

public static implicit operator bool($classname$ other){
    return other != null;
}
Run Code Online (Sandbox Code Playgroud)

Unity计划删除此功能,但决定反对它,因为它会破坏每个Unity代码.你可以在这里阅读更多相关信息.

这个功能非常糟糕的一面是它无法在编辑器中使用Null-Coalescing运算符功能.好的一面是它简化了检查null.