Can object constructor return a null?
我们已经接管了一些.NET 1.1 Windows服务代码,这些代码生成线程来从队列中读取消息(请参见egate jms队列,但这并不重要),然后生成线程来处理目标应用程序服务中的消息。我们不断地遇到逻辑和设计决策,这让我们困惑不已。下面是一个示例,其中消息(lsmessage)已从队列中检索并准备好进行处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | if(lsMessage != null) { // Initialize a new thread class instance, pass in message WorkerThread worker = new WorkerThread(lsMessage); Process: // Start a new thread to process the message Thread targetWorker = new Thread(new ThreadStart(worker.ProcessMessage)); if(targetWorker != null) { targetWorker.Priority = ThreadPriority.Highest; targetWorker.Name ="Worker" + queueKey.ToString(); targetWorker.Start(); // wait for worker thread to join back in specified period bool isFinished = targetWorker.Join(SYNC_THREAD_TIMEOUT); string message = worker.replyMsg; if ( !isFinished ) // BF is timeout { targetWorker.Abort(); // [obscure developer name] 25/10/2004: calling Join() to wait for thread to terminate. // for EAI listener threads problem, ensure no new thread is started // before the old one ends targetWorker.Join(); // prepare reply message string errorMsg = string.Format("EAIMsg {0}: BF is timeout. Send sync message back to caller.", worker.messageKey); log.Debug(errorMsg); message = worker.GenErrorCode(message, errorMsg); } // Commit message MQ.ReceiverCommit(queueKey, worker.messageKey, false); // Send back the response to the caller MQ.RespondSend(queueKey, message); } else { log.Debug(string.Format("Fail to start worker thread to process sync message. Thread returned is null. Sleep for {0} milliseconds.", LIMIT_RESOURCE_SLEEP)); Thread.Sleep(LIMIT_RESOURCE_SLEEP); goto Process; } } |
请忽略标签的使用,暂时转到;这不是问题。我们的困惑是在实例化之后检查线程对象是否为空。下面的else语句似乎表明以前的开发人员遇到过类似的情况。当然,最初的开发人员早就不见了。所以我们想知道,在调用构造函数并返回一个空值之后,clr真的能实例化一个对象吗?我们不知道这种可能性。
在我看来,
在过去的年代,C++构造函数可以返回EDCOX1×0,因此问题可能来自于此。这在C++中也不再是正确的,至少对于默认的EDOCX1·7Ω操作符来说是这样。
编辑:为了澄清这一点,有一个疯狂的边缘案例,你可以从类构造函数中获得
不,不能从类构造函数(
1 | object foo = new int?(); // this is null |
这是仿制药的一个稍大的问题:
1 2 3 4 5 6 7 8 | static void Oops<T>() where T : new() { T t = new T(); if (t == null) throw new InvalidOperationException(); } static void Main() { Oops<int?>(); } |
(当然,也有检查/处理这种情况的方法,如
除此之外,构造函数总是返回一个对象(或初始化一个结构),或者抛出一个异常。
正如
这将在运行时编译和记录消息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | using UnityEngine; public class Test:MonoBehaviour { void Start() { AudioSource as = new AudioSource(); if (as == null) { Debug.Log("Looks null to me."); } } } |
现在,这里的错误是我的,因为不应该直接调用
Be careful when comparing with null.
e.g.
1
2
3
4
5 GameObject go = new GameObject();
Debug.Log (go == null); // false
Object obj = new Object();
Debug.Log (obj == null); // trueInstatiating a GameObject adds it to the scene so it's completely
initialized (!destroyed). Instantiating a simple UnityEngine.Object
has no such semantics, so the(sic) it stays in the 'destroyed' state which
compares true to null.
当实例化一个
由于试图引用未初始化的
其他人回答了OP的问题,但我想补充这个答案,因为如果其中的
可以使其看起来像对象ctor返回空值:
Returning null from a class constructor?!
搜索"另一个我没见过使用的模式允许一个无效对象模拟一个空引用",然后从中读取。
不!空检查是多余的。很多搬到C++的C++开发者都有一个空校验的习惯,我猜这里是一样的。
唯一的事情是,您应该检查文档,看看构造函数是否可以抛出任何异常。在您的情况下,请参阅http://msdn.microsoft.com/en-us/library/xx3ezzs2.aspx,如前所述,构造函数将始终返回有效的obj。