Недавно я столкнулся с каким-то странным поведением моего приложения. Он был разработан в основном на С#, но CLI/С++ также использовался для достижения лучшей производительности. Я получал исключение System.NullReferenceException в очень простом методе при сравнении TimeSpan:
TimeSpan _timestamp;
void UpdateFrame(TimeSpan timestamp)
{
if(TimeSpan::Equals(_timestamp, timestamp) == false)
Было очевидно, что единственная ссылка, используемая в этом выражении, была неявной (this._timestamp). Я добавил утверждение assert, и оказалось, что это фактически null. После короткого расследования мне удалось подготовить короткую программу, представляющую это явление. Это С++/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;
}
Кто-нибудь знает, как это возможно? Это ошибка в компиляторе?