469,623 Members | 1,683 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,623 developers. It's quick & easy.

How to get ValueType default for DBNull column using reflection?

I have properties that wrap DataRow columns as in:
public int aNumber
{ get{ return m_DataRow["aColumnName"]; }
set{ m_DataRow["aColumnName"] = value; } }

If the column happens to contain DBNull, I get a cast
exception since DBNull cannot be converted to int. I
wrote the following method that looks up the column's
data type and if it is a ValueType, returns the default
value for the ValueType.

I want the method to use reflection to get the default
value, so I don't have to code for each data type. However,
GetConstructor always returns null. Is there some other
way to get the default value for a ValueType?

Thanks,

Brian Brane

Here's the method...

// Instance variables containing default values (work around)
bool m_Bool;
byte m_Byte;
DateTime m_DateTime;
Guid m_Guid;
int m_Int;

private object GetColumnValueOrDefault(DataRow dataRow, string columnName)
{
DataColumn column = dataRow.Table.Columns[columnName];
if (column == null)
throw new Exception("Invalid column name: " + columnName);

// If the column contains a value, then return the value
object value = dataRow[column];
if (value != System.DBNull.Value)
return value;

// If the column is not a ValueType, then return null
System.Type dataType = column.DataType;
if (!dataType.IsValueType)
return null;

// Use reflection to create a new ValueType
System.Reflection.ConstructorInfo constructor =
dataType.GetConstructor(System.Type.EmptyTypes);
if (constructor != null) //// IS ALWAYS NULL!
{
object defaultValue = constructor.Invoke(new object[0]);
return defaultValue;
}

// Return a ValueType that is initialized to its default value
if (dataType == typeof(System.Boolean))
return m_Bool;

if (dataType == typeof(System.Byte))
return m_Byte;

if (dataType == typeof(System.DateTime))
return m_DateTime;

if (dataType == typeof(System.Guid))
return m_Guid;

if (dataType == typeof(System.Int32))
return m_Int;

throw new Exception("Unable to determine default for " + columnName);
}
Nov 15 '05 #1
4 9719
IsDbNull(), iirc.

"Brian Brane" <br*********@msn.com> wrote in message
news:24**************************@posting.google.c om...
I have properties that wrap DataRow columns as in:
public int aNumber
{ get{ return m_DataRow["aColumnName"]; }
set{ m_DataRow["aColumnName"] = value; } }

If the column happens to contain DBNull, I get a cast
exception since DBNull cannot be converted to int. I
wrote the following method that looks up the column's
data type and if it is a ValueType, returns the default
value for the ValueType.

I want the method to use reflection to get the default
value, so I don't have to code for each data type. However,
GetConstructor always returns null. Is there some other
way to get the default value for a ValueType?

Thanks,

Brian Brane

Here's the method...

// Instance variables containing default values (work around)
bool m_Bool;
byte m_Byte;
DateTime m_DateTime;
Guid m_Guid;
int m_Int;

private object GetColumnValueOrDefault(DataRow dataRow, string columnName)
{
DataColumn column = dataRow.Table.Columns[columnName];
if (column == null)
throw new Exception("Invalid column name: " + columnName);

// If the column contains a value, then return the value
object value = dataRow[column];
if (value != System.DBNull.Value)
return value;

// If the column is not a ValueType, then return null
System.Type dataType = column.DataType;
if (!dataType.IsValueType)
return null;

// Use reflection to create a new ValueType
System.Reflection.ConstructorInfo constructor =
dataType.GetConstructor(System.Type.EmptyTypes);
if (constructor != null) //// IS ALWAYS NULL!
{
object defaultValue = constructor.Invoke(new object[0]);
return defaultValue;
}

// Return a ValueType that is initialized to its default value
if (dataType == typeof(System.Boolean))
return m_Bool;

if (dataType == typeof(System.Byte))
return m_Byte;

if (dataType == typeof(System.DateTime))
return m_DateTime;

if (dataType == typeof(System.Guid))
return m_Guid;

if (dataType == typeof(System.Int32))
return m_Int;

throw new Exception("Unable to determine default for " + columnName);
}

Nov 15 '05 #2
Brian,

I'm confused about what you're trying to accomplish.

DataRow.IsDBNull() can tell you if the value in a column is a null. If you
want to return a "default value" for nulls, then you probably want to create
an attribute for the property or field to define what the "default value" is
for those properties or fields.

To create an instance, you want to use Activator.CreateInstance() which will
create an instance of an object. I don't think calling the constructor
directly will work, since creating an instance doesn't just involve calling
the constructor, but allocating the memory for the object first.

Hope that helps, and if I've erred, I hope someone else will point it out.

Pete

"Brian Brane" <br*********@msn.com> wrote in message
news:24**************************@posting.google.c om...
I have properties that wrap DataRow columns as in:
public int aNumber
{ get{ return m_DataRow["aColumnName"]; }
set{ m_DataRow["aColumnName"] = value; } }

If the column happens to contain DBNull, I get a cast
exception since DBNull cannot be converted to int. I
wrote the following method that looks up the column's
data type and if it is a ValueType, returns the default
value for the ValueType.

I want the method to use reflection to get the default
value, so I don't have to code for each data type. However,
GetConstructor always returns null. Is there some other
way to get the default value for a ValueType?

Thanks,

Brian Brane

Here's the method...

// Instance variables containing default values (work around)
bool m_Bool;
byte m_Byte;
DateTime m_DateTime;
Guid m_Guid;
int m_Int;

private object GetColumnValueOrDefault(DataRow dataRow, string columnName)
{
DataColumn column = dataRow.Table.Columns[columnName];
if (column == null)
throw new Exception("Invalid column name: " + columnName);

// If the column contains a value, then return the value
object value = dataRow[column];
if (value != System.DBNull.Value)
return value;

// If the column is not a ValueType, then return null
System.Type dataType = column.DataType;
if (!dataType.IsValueType)
return null;

// Use reflection to create a new ValueType
System.Reflection.ConstructorInfo constructor =
dataType.GetConstructor(System.Type.EmptyTypes);
if (constructor != null) //// IS ALWAYS NULL!
{
object defaultValue = constructor.Invoke(new object[0]);
return defaultValue;
}

// Return a ValueType that is initialized to its default value
if (dataType == typeof(System.Boolean))
return m_Bool;

if (dataType == typeof(System.Byte))
return m_Byte;

if (dataType == typeof(System.DateTime))
return m_DateTime;

if (dataType == typeof(System.Guid))
return m_Guid;

if (dataType == typeof(System.Int32))
return m_Int;

throw new Exception("Unable to determine default for " + columnName);
}

Nov 15 '05 #3
What I want is the default value for the ValueType of the
column such as 0 for int, false for bool, and Guid.Empty
for a Guid. I was able to get this by creating a 1-element
array of the ValueType:

Array array = Array.CreateInstance(dataType, 1);
return array.GetValue(0);

Seems like there should be a more direct method, but this
gives what I want.

Thanks,

Brian Brane
Nov 15 '05 #4
C# 2.0 is supposed to have a direct way to do it, but it MAY only work with
Generics. We'll see when the beta gets here.

I like your solution, though. I was trying to come up a way to use the
serializer to do what you want, but your solution is much simpler.

--Matthew W. Jackson

"Brian Brane" <br*********@msn.com> wrote in message
news:24**************************@posting.google.c om...
What I want is the default value for the ValueType of the
column such as 0 for int, false for bool, and Guid.Empty
for a Guid. I was able to get this by creating a 1-element
array of the ValueType:

Array array = Array.CreateInstance(dataType, 1);
return array.GetValue(0);

Seems like there should be a more direct method, but this
gives what I want.

Thanks,

Brian Brane

Nov 15 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by Patrick.O.Ige | last post: by
2 posts views Thread by mjwills | last post: by
6 posts views Thread by vvenk | last post: by
9 posts views Thread by Robert Bravery | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.