IComparable
インターフェイスを実装していない.NETクラスがありました。このクラスにインターフェイスを実装した後IComparable
、クラスを使用するいくつかのC ++コードによって、予期しない動作が変更されました。今それは投げますNullReferenceException
DWORD UnitsAdapter::GetUnitNames([Out]array<MyClass^>^% unitNames)
{
...
unitNames = gcnew array<MyClass^>(10);
DWORD dwRet = BUMC_OK;
for (int i = 0; i < unitNames->Length; ++i)
{
unitNames[i] = nullptr;
unitNames[i] = CoCliUnitsHelper::getUnitName(unitIds[i]);
if (nullptr == unitNames[i])
dwRet = BUMC_NOT_COMPLETE;
}
return dwRet;
}
問題は、実装を使用して操作を実行しif (nullptr == unitNames[i])
始めた行にありました。IComparable
==
その理由は、cliext
ユーティリティヘッダーファイルからのテンプレートでした。
//
// System::IComparable TEMPLATE COMPARISONS
//
template<typename _Value_t>
bool operator==(System::IComparable<_Value_t>^ _Left,
System::IComparable<_Value_t>^ _Right)
{ // test if _Left == _Right
return (_Left->CompareTo(_Right) == 0);
}
質問1:_Left
私はC ++の専門家ではないので、この実装がメソッドを呼び出す前にnullチェックを実行しない理由を誰かが説明できますCompareTo()
か?Equals()とOperator ==のオーバーロードに関するMSDNガイドラインによると内で何かを実行する前にnullチェックを実行する必要があります==
。
...
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
...
質問2:そのような予測できない動作につながる使用法の欠陥はおそらくありますか?