在标准的.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.