One of the weirder features in C# 2.0 is nullable types. My thinking is as follows: Why complicate things with Nullable, or its shorter version of DataType? (i.e. int?), instead of allowing null values to be assigned to those data types that don't have any way of handling null? Maybe it was a matter of not breaking the framework or introducing changes gradually. Also, code such as that below will cause the compiler to error as nullable types and their non-nullable type equivelent are treated as 2 different types.
int
? m_Value1;
// The shorter version of Nullable m_Value1
m_Value1 =
int
.Parse(Request.QueryString[
"SomeNumberParam"
]);
int
m_Value2;
if
(m_Value1 !=
null
)
// Nullable types can be checked for null
{
m_Value2 = m_Value1;
// Won't compile
m_Value2 = (
int
)m_Value1;
// Will compile
}
Hopefully, in the next version of C#, nullable types will be replaced with the ability for their non-nullable versions to handle null, like below:
int
m_Value1, m_Value2;
m_Value1 =
int
.Parse(Request.QueryString[
"SomeNumberParam"
]);
if
(m_Value1 !=
null
)
{
m_Value2 = m_Value1;
}
Do you dare ask what this non-sense looks like in code form? In case you are wondering, I'm using the non-nullable form of the word form. Sorry if I've confused you by including the ? after form in order to form a question. I now present you with non-sense:
using
System;
using
System.Runtime.CompilerServices;
using
System.Runtime.InteropServices;
[
Serializable
,
StructLayout
(
LayoutKind
.Sequential),
TypeDependency
(
"System.Collections.Generic.NullableComparer`1"
),
TypeDependency
(
"System.Collections.Generic.NullableEqualityComparer`1"
)]
public
struct
Nullable
where
T :
struct
{
private
bool
hasValue;
internal
T value;
public
Nullable(T value)
{
this
.value = value;
this
.hasValue =
true
;
}
public
bool
HasValue
{
get
{
return
this
.hasValue;
}
}
public
T Value
{
get
{
if
(!
this
.HasValue)
{
ThrowHelper
.ThrowInvalidOperationException(
ExceptionResource
.InvalidOperation_NoValue);
}
return
this
.value;
}
}
public
T GetValueOrDefault()
{
return
this
.value;
}
public
T GetValueOrDefault(T defaultValue)
{
if
(!
this
.HasValue)
{
return
defaultValue;
}
return
this
.value;
}
public
override
bool
Equals(
object
other)
{
if
(!
this
.HasValue)
{
return
(other ==
null
);
}
if
(other ==
null
)
{
return
false
;
}
return
this
.value.Equals(other);
}
public
override
int
GetHashCode()
{
if
(!
this
.HasValue)
{
return
0;
}
return
this
.value.GetHashCode();
}
public
override
string
ToString()
{
if
(!
this
.HasValue)
{
return
""
;
}
return
this
.value.ToString();
}
public
static
explicit
operator
T(
Nullable
value)
{
return
value.get_Value();
}
public
static
implicit
operator
Nullable
(T value)
{
return
new
Nullable
(value);
}
}