我有一个没有实现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
implementation 执行==
操作的行中!
原因是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:我不是 c++ 专家,所以有人可以解释一下为什么这个实现_Left
在调用CompareTo()
方法之前不执行 null 检查吗?根据MSDN Guidelines for Overloading Equals() 和 Operator == 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:是否存在导致这种不可预测行为的使用缺陷?