在标准.NET 4.6编译器中,以下if语句不合法,将出现编译器错误:cs0029无法隐式将类型“userquery.testClass”转换为“bool”。这一切都很好,我理解。

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

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


public class TestClass : Object
{
}

然而,在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.");
        }
    }
}

情节变粗了!如果我尝试比较一个不是从mono行为派生的对象,就会得到预期的编译器警告。
public class TestClass
{
}
void Start ()
{
    var obj2 = new TestClass();
    if (obj2) // cast from TestClass to bool compiler error
    {

    }
}

多亏了程序员,我一路深入到Unity3D的对象(我忽略了它,因为我误以为它是.NET的实际对象)。
好奇者的相关代码(单位:engine.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);
}

最佳答案

不要太担心这个。if (obj)只在unity中合法,因为unity中存在隐式运算符重载。我相信这是在MonoBehaviourUnityEngine.Object课上完成的。
看起来像这样:

public static implicit operator bool($classname$ other){
    return other != null;
}

unity计划删除这个特性,但决定反对它,因为它会破坏所有unity代码。您可以阅读更多关于here的内容。
这个特性非常糟糕的一面是,它使得无法在编辑器中使用空合并运算符特性。好的一面是它简化了对null的检查。

关于c# - 为什么Unity3d C#中的语句允许不是 bool 对象?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45557578/

10-11 21:24