65.9K
CodeProject 正在变化。 阅读更多。
Home

CNullable<T>:C++/CLI 的便捷 Nullable<T> 等效类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (18投票s)

2005年5月18日

2分钟阅读

viewsIcon

64586

downloadIcon

581

CNullable<T> 可用于表示一个值类型(或简单的原生类型),使其能够为 null。您还可以使用重载的 == 和 != 运算符将其与 nullptr 进行比较。

概述

从 Whidbey 开始,C# 支持可空类型(可以为 nullvalue 类型),它使用 mscorlib 程序集中定义的 System::Nullable<T> generic 类来实现。它还提供了一个快捷方式形式 T? var,对应于 System.Nullable<T> var。请看下面的 C# 代码片段:

int? q1 = null;

if (q1.HasValue)
    Console.WriteLine(q1.Value);
else
    Console.WriteLine("It's null");    

q1 = 99;
q1++;

int? q2 = q1;
if (q2 != null)
{
    q2 = null;
}

现在,请看对应的 C++ 代码(C# 代码在注释中):

//int? q1 = null;
Nullable<int> q1;

//if (q1.HasValue)
//    Console.WriteLine(q1.Value);
//else
//    Console.WriteLine("It's null");

if(q1.HasValue)
    Console::WriteLine(q1.Value);
else
    Console::WriteLine("It's null");

//q1 = 99;

q1 = Nullable<int>(99);

//q1++;

if(q1.HasValue)
    q1 = Nullable<int>(q1.Value + 1);

//int? q2 = q1;

Nullable<int> q2 = q1;

//if (q2 != null)
//{
//    q2 = null;
//}

if( q2.HasValue )
{
    q2 = Nullable<int>();
}

不是很方便,对吧?现在看看这段 C++ 代码:

//int? q1 = null;
CNullable<int> q1;

//if (q1.HasValue)
//    Console.WriteLine(q1.Value);
//else
//    Console.WriteLine("It's null");

if(q1.HasValue)
    Console::WriteLine(q1.Value);
else
    Console::WriteLine("It's null");

//q1 = 99;

q1 = 99;

//q1++;

(*q1)++;

////int? q2 = q1;

CNullable<int> q2 = q1;

//if (q2 != null)
//{
//    q2 = null;
//}

if(q2 != nullptr)
{
    q2 = nullptr;
}

就易用性而言,这比 C# 代码要方便得多,不是吗?这就是我为 C++/CLI 编写 CNullable<> template ref 类的原因。

类参考

template<typename T> ref class CodeProject::Extra::CNullable sealed : INullableValue

CNullable 可用于表示一个值类型(或简单的原生类型),使其能够为 null。您还可以使用重载的 ==!= 运算符将其与 nullptr 进行比较。

构造函数

  • CNullable()

    默认构造函数创建一个被赋值为 nullptrCNullable 对象。

    CNullable<char> x1;
  • CNullable(void* p)

    此重载处理将 nullptr 传递给构造函数的情况。如果传入的指针不是 nullptr,则会抛出 InvalidOperationException

    CNullable<double> x2(nullptr);
  • CNullable(const T% t)

    使用传入的模板参数类型构造一个 CNullable 对象。

    CNullable<int> x3(100);
  • CNullable(const CNullable% n)

    复制构造函数。

    CNullable<int> x4(x3);

运算符

  • operator T()

    转换为类型 T。

    注意 - 如果对象当前为 null,则会抛出 InvalidOperationException

    int y = x4;
  • void operator =(void* p)

    处理 nullptr 情况的赋值运算符。

    注意 - 如果 p 是一个非 null 指针,则会抛出 InvalidOperationException

    x3 = nullptr;
  • const T operator =(const T% t)

    类型 T 的赋值运算符。

    x4 = x3 = 13;
  • T% operator*()

    通过重载解引用运算符来暴露底层类型。

    x5 = (*x4)++;
  • bool operator ==(void* p)

    允许与 nullptr 进行 == 比较。

    if( x5 == nullptr )
    {
    }
  • bool operator !=(void* p)

    允许与 nullptr 进行 != 比较。

    if( x5 != nullptr )
    {
    }
  • operator String^()

    提供类型的字符串表示。内部调用 ToString 方法。

    Console::WriteLine( (String^)x5 );

方法

  • virtual String^ ToString() override

    如果对象当前为 null,则返回一个空字符串,否则调用底层模板参数类型成员的 ToString 方法并返回该字符串。

    Console::WriteLine( x5.ToString() );
  • Nullable<T> CreateNullable()

    创建一个新的 Nullable<T> 对象(用于与显式需要 Nullable<T> 的 .NET 代码进行交互)。通常,由于 CNullable 对象实现了 INullableValue,您可以直接传递它。

    Nullable<int> n1 = x5.CreateNullable();
  • static CNullable^ FromNullable(Nullable<T> n)

    静态方法,用于从 Nullable<T> 对象创建新的 CNullable 对象。

    CNullable<int> x6 = CNullable<int>::FromNullable(n1);

属性

  • property virtual bool HasValue::get

    INullableValue::HasValue 的实现。指示值是否有效,或者是否为 null 值。

    if(x6.HasValue)
  • property virtual Object^ Value::get

    INullableValue::Value 的实现。如果 HasValuetrue,则返回内部模板参数类型成员的值,否则抛出 InvalidOperationException 异常。

    Console::WriteLine(x6.Value);

历史

  • 2005 年 5 月 18 日:文章首次在 The Code Project 上发布。
© . All rights reserved.