Dot-Net

this == null // 怎麼可能?

  • April 20, 2010

最近我遇到了我的應用程序的一些奇怪行為。它主要使用 C# 開發,但也使用 CLI/C++ 來實現更好的性能。在 TimeSpan 比較中,我以一種非常簡單的方法得到了 System.NullReferenceException:

TimeSpan _timestamp;
void UpdateFrame(TimeSpan timestamp)
{
   if(TimeSpan::Equals(_timestamp, timestamp) == false) 

很明顯,這個表達式中使用的唯一引用是隱含的 this (this._timestamp)。我添加了一個斷言語句,結果證明這實際上是空的。經過短暫的調查,我設法準備了介紹這種現象的短節目。它是 C++/CLI。

using namespace System;
using namespace System::Reflection;

public class Unmanaged
{
public:
   int value;
};

public ref class Managed
{
public:
   int value;

   Unmanaged* GetUnmanaged()
   {
       SampleMethod();
       return new Unmanaged();
   }

   void SampleMethod()
   {
       System::Diagnostics::Debug::Assert(this != nullptr);
       this->value = 0;
   }
};

public ref class ManagedAccessor
{
public:
   property Managed^ m;
};

int main(array<System::String ^> ^args)
{
   ManagedAccessor^ ma = gcnew ManagedAccessor();
   // Confirm that ma->m == null
   System::Diagnostics::Debug::Assert(ma->m == nullptr);
   // Invoke method on the null reference
   delete ma->m->GetUnmanaged();
   return 0;
}

有誰知道這怎麼可能?它是編譯器中的錯誤嗎?

在 C++ 中(可能是在 C++/CLI 中),沒有什麼可以阻止您嘗試在 NULL 指針上呼叫方法。在大多數實現中,虛擬方法呼叫將在呼叫點崩潰,因為執行時將無法讀取虛擬方法表。但是,非虛擬方法呼叫只是帶有一些參數的函式呼叫,其中一個參數是this指針。如果它為空,那麼這就是傳遞給函式的內容。

NULL我相信在(或)指針上呼叫任何成員函式的結果nullptr是正式的“未定義行為”。

引用自:https://stackoverflow.com/questions/2679080