c# - STL/CLR 库使用 IComparable 实现 == 运算符并抛出 NullReferenceException

标签 c# c++ .net cliext

我有一个 .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/

相关文章:

c# - 在运行时更改 PropertyGrid Description 和 Category 属性

c# - 匹配双括号中的单词的正则表达式是什么

c# - 如何从可空类型获取字符串表示形式?

c++ - 这个指针的使用

c# - IIS 反向代理后面的 Web 应用程序在通过 OIDC 对外部 IdentityServer 进行身份验证时设置了错误的 signin_oidc redirect_uri

c++ - 如何克服 "undefined reference to _M_insert_aux()"?

c++ - 是否可以使用 QT 制作一个 2 面按钮?

c# - 从字符串 C# 进行日期时间转换

c# - 从后面的 C# 代码调用 JavaScript

javascript - 带有复选框的 Gridview