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

在标准的.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."); } } } 

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

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

感谢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); } 

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

它看起来像这样:

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

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

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