Working with an unknown Nullable<> type.

E

ESPNSTI

Hi,

Please don't shoot me if the answer is simple, I'm new to .Net and C# :)
..
I'm attempting to convert a nullable type to it's "non-nullable" type in a
generic way (without knowing what specific type the nullable type is.)
The reason I'm trying this is because when I attempt to pass a nullable type
value to a SqlCommand parameter and then attempt to execute it I the
following error:
"No mapping exists from object type System.Nullable`1[[System.DateTime,
mscorlib, Version=2.0.3600.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]] to a known managed provider native type."

If you take a look below, I think I found a way to at least detect if
"value" is a Nullable type or not. (Not sure if that's the right way to do
it.)
However I haven't found a way to typecast the "value" variable so that I can
use the Nullable type's methods and properties.
When I try "(Object?)value", I get a "Specified cast is not valid." /
"Cannot unbox 'value' as a 'object?'" error.

How do I typecast the value variable so that I can access the Nullable
methods and properties?
(I know (DateTime?)value works, but I don't know that it's a DateTime
nullable type and I don't want to end up with a big case statement for a
bunch of types).

Thanks,
Erik



The code:
____________________________________________________________________________
_____________

// Setting it to a DateTime? nullable value here, in my actual code I
don't know that it's a DateTime? type.
object value = (DateTime?)DateTime.Parse("01/01/2005");

Type valueType = value.GetType();
// Check if it is a nullable type.
if (valueType.HasGenericArguments &&
valueType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
// See if it has a value.
if (((Object?)value).HasValue) //<-- This doesn't work, get a "Cannot
unbox 'value' as a 'object?'" error
// It does have a value, "convert" the value variable to a
"non-nullable" type.
value = ((Object?)value).ToObject();
else
// It doesn't have a value, use null
value = null;
____________________________________________________________________________
_____________
 
C

Cordell Lawrence

Use the INullableValue (using Beta 2) interface that Nullable< T >
implements.

public int InsertRecord(DateTime? sampleDate, int? sampleInt);
{
this.command.Parameters["@sampleDate"].Value = (sampleDate as
INullableValue).Value;
this.command.Parameters["@sampleInt"].Value = (sampleInt as
INullableValue).Value;

return this.command.ExecuteNonQuery();
}

HTH,
Cordell Lawrence
Teleios Systems Ltd.
 
E

ESPNSTI

Worked like a charm, thank you very much!

This is the code I ended up with:

object value = (DateTime?)DateTime.Parse("01/01/2005");
if (value is INullableValue)
if ((value as INullableValue).HasValue)
value = (value as INullableValue).Value;
else
value = null;
 
C

Cordell Lawrence

No problem,
Some other advice: Looking at your code snippet, you're doing some extra
checks that arn't necessary
The following code will do the exact same thing:

object value = (((DateTime?)DateTime.Parse( "01/01/2005" )) as
INullableValue).Value;

If the value of the expresseion (DateTime?)DateTime.Parse(...) is null then
value will be null, else it will be your 'actual value'.
You don't need to check that it implements INullableValue, you can be sure
of that as long as you expression follows the format:

(<Type>?)<expression>

You also don't need to check the HasValue property, just take the Value
property off the interface if it has no value you'll get null, otherwise
you'll get your 'value'.

HTH
Cordell Lawrence
Teleios Systems Ltd.
 
E

ESPNSTI

Thanks again for your help.
You don't need to check that it implements INullableValue, you can be sure
of that as long as you expression follows the format:

(<Type>?)<expression>

The reason I'm checking for INullableValue is that in my "real world"
scenario, I don't know that the value variable is a "DateTime?", it could be
a regular "DateTime" or an "Int" or anything else.
In the case that it isn't a Nullable type, it would end up overwriting the
existing value with null, which is not what I want.
You also don't need to check the HasValue property, just take the Value
property off the interface if it has no value you'll get null, otherwise
you'll get your 'value'.

Perhaps this was changed in Beta 2 (I'm still working with Beta 1), but when
I directly use Value without checking HasValue, I get empty instead of null.
For example value will hold "01/01/0001" after this statement:
object value = (((DateTime?)null) as INullableValue).Value;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top