我有一个 .NET 类没有实现 IComparable
接口(interface)。
在我在此类上实现 IComparable
接口(interface)后,一些使用我的类的 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:我不是 C++ 专家,所以有人能解释一下为什么这个实现不对 _Left
执行空检查吗在调用 CompareTo()
方法之前?根据MSDN Guidelines for Overloading Equals() and Operator ==在 ==
运算符中执行任何操作之前,必须先进行空检查。
...
// 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: 是否可能存在导致这种不可预测行为的使用缺陷?
最佳答案
so can someone explain me why this implementation does not perform a null check on _Left before calling CompareTo() method
因为编写它的人忽略了检查空值。
Is there probably some flaw in usage which leads to such an unpredictable behavior?
好吧,将空指针与某物进行比较可能是一种极端情况,但我当然不会将其称为“缺陷”。 ==
的实现不正确。
要解决此问题,您可以撤销相等性检查和/或检查 null
:
if (unitNames[i] == nullptr)
dwRet = BUMC_NOT_COMPLETE;
关于c# - STL/CLR 库使用 IComparable 实现 == 运算符并抛出 NullReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13346081/