2008-12-05

PropertyInfo.PropertyType - is it Nullable?

Here's what I learned in school today.

I extended an object in our product with some nullable data types (something that, maddeningly, the previous programmers seemed to have an aversion to using, preferring instead to passing around "magic numbers" to represent null values — nice work, guys). Unfortunately, it bombed in one screen that used reflection to take objects and make datasets out of them.

The offending section of code looked like this:

PropertyInfo[] pInfo = myType.GetProperties();
for (int i = 0; i < pInfo.Length; i++) {
    DataColumn dCol = new DataColumn();
    dCol.ColumnName = pInfo[i].Name;
    dCol.DataType = pInfo[i].PropertyType;
    resultTable.Columns.Add(dCol);
}

The error thrown was that datasets don't support the "System.Nullable" type. Well, technically, they do, in that everything is nullable in a dataset, but that's beside the point. The solution is, I need, when building this dataset, to see if the type is Nullable, and if so, use the underlying type instead. No problem, right?

Not if you happen upon this post by the user "OregonGhost" on StackOverflow.com. He may not have invented the solution, I don't know; I just know that after searching for a bit, his post was the first answer I actually found to my question.

My code now looks like this:

PropertyInfo[] pInfo = myType.GetProperties();
for (int i = 0; i < pInfo.Length; i++) {
    DataColumn dCol = new DataColumn();
    dCol.ColumnName = pInfo[i].Name;
    Type dataType = pInfo[i].PropertyType;
    if (dataType.IsGenericType && dataType.GetGenericTypeDefinition() == typeof(System.Nullable<>)) {
        dataType = System.Nullable.GetUnderlyingType(dataType);
    }
    dCol.DataType = dataType;
    resultTable.Columns.Add(dCol);
}

And it works.

2 comments:

Jim said...

Nice work. This is exactly what I was looking for.

Dave said...

Heeeellllooo nurse! Had to do it. This is exactly what I needed for my T4 template. I also set a bool if the type is Nullable so I can output the '?' after the propertyType.Name. Thanks.

P.S. Regards to Dot.