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






4.80/5 (18投票s)
2005年5月18日
2分钟阅读

64586

581
CNullable<T> 可用于表示一个值类型(或简单的原生类型),使其能够为 null。您还可以使用重载的 == 和 != 运算符将其与 nullptr 进行比较。
概述
从 Whidbey 开始,C# 支持可空类型(可以为 null
的 value
类型),它使用 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()
默认构造函数创建一个被赋值为
nullptr
的CNullable
对象。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
的实现。如果HasValue
为true
,则返回内部模板参数类型成员的值,否则抛出InvalidOperationException
异常。Console::WriteLine(x6.Value);
历史
- 2005 年 5 月 18 日:文章首次在 The Code Project 上发布。