CNullable<T> : A convenient Nullable<T> equivalent class for C++/CLI






4.80/5 (18 votes)
May 18, 2005
2 min read

64162

581
CNullable<T> can be used to represent a value type (or simple native type) such that the type can be nulled. You can also compare it to nullptr using the == and != operators both of which have been overloaded.
Overview
Starting with Whidbey, C# supports nullable types (value
types that can also
be null
) and it does this using the System::Nullable<T>
generic
class defined in the mscorlib assembly. It also provides a
short-cut form, T? var
which corresponds to System.Nullable<T>
var
. Take a look at the following C# code snippet :-
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;
}
Now, take a look at the corresponding C++ code (C# code in comments) :-
//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>();
}
Not very convenient, is it? Now look at this C++ code :-
//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;
}
Well, that's a lot more closer to the C# code as far as ease-of-use is
concerned, is it not? That's why I wrote my CNullable<>
template ref
class for C++/CLI.
Class Reference
template<typename T> ref class CodeProject::Extra::CNullable sealed :
INullableValue
CNullable
can be used to represent a value type (or simple native type) such
that the type can be nulled. You can also compare it to nullptr
using
the ==
and !=
operators both of which have been overloaded.
Constructors
-
CNullable()
The default constructor creates a
CNullable
object assigned tonullptr
.CNullable<char> x1;
-
CNullable(void* p)
This overload handles the case where a
nullptr
is passed to the constructor. If the pointer passed is not anullptr
, anInvalidOperationException
gets thrown.CNullable<double> x2(nullptr);
-
CNullable(const T% t)
Constructs a
CNullable
object using the passed in template-argument type.CNullable<int> x3(100);
-
CNullable(const CNullable% n)
Copy constructor.
CNullable<int> x4(x3);
Operators
-
operator T()
Converts to type T.
Note - If the object is currently nulled, an
InvalidOperationException
is thrown.int y = x4;
-
void operator =(void* p)
Assignment operator that handles the
nullptr
case.Note - If
p
is a non-null pointer, anInvalidOperationException
is thrown.x3 = nullptr;
-
const T operator =(const T% t)
Assignment operator for type T.
x4 = x3 = 13;
-
T% operator*()
The underlying type is exposed by overloading the dereference operator.
x5 = (*x4)++;
-
bool operator ==(void* p)
Allows
==
comparison withnullptr
.if( x5 == nullptr ) { }
-
bool operator !=(void* p)
Allows
!=
comparison withnullptr
.if( x5 != nullptr ) { }
-
operator String^()
Gives the string representation of the type. Internally calls the
ToString
method.Console::WriteLine( (String^)x5 );
Methods
-
virtual String^ ToString() override
Returns an empty string if the object is currently nulled, else calls
ToString
on the underlying template-argument type member and returns that string.Console::WriteLine( x5.ToString() );
-
Nullable<T> CreateNullable()
Creates a new
Nullable<T>
object (useful to interact with .NET code that explicitly expects aNullable<T>
). Normally you'd be able to pass aCNullable
object directly since it implementsINullableValue
.Nullable<int> n1 = x5.CreateNullable();
-
static CNullable^ FromNullable(Nullable<T> n)
Static method to create a new
CNullable
object from aNullable<T>
object.CNullable<int> x6 = CNullable<int>::FromNullable(n1);
Properties
-
property virtual bool HasValue::get
Implementation of
INullableValue::HasValue
. Indicates whether the value is valid or whether it's a null-value.if(x6.HasValue)
-
property virtual Object^ Value::get
Implementation of
INullableValue::Value
. IfHasValue
istrue
, it returns the value of the internal template argument type member, otherwise throws anInvalidOperationException
exception.Console::WriteLine(x6.Value);
History
- May 18th, 2005 : Article first published on The Code Project.