views:

416

answers:

3

Hi Guys

I have a block of code that serializes a type into a Html tag.

Type t = typeof(T); // I pass <T> in as a paramter, where myObj is of type T
tagBuilder.Attributes.Add("class", t.Name);
foreach (PropertyInfo prop in t.GetProperties())
{
    object propValue = prop.GetValue(myObj, null);
    string stringValue = propValue != null ? propValue.ToString() : String.Empty;
    tagBuilder.Attributes.Add(prop.Name, stringValue);
}

This works great, except I want it to only do this for primitive types, like int, double, bool etc, and other types that aren't primitive but can be serialized easily like string. I want it to ignore everything else like Lists & other custom types.

Can anyone suggest how I do this? Or do I need to specify the types I want to allow somewhere and switch on the property's type to see if it's allowed? That's a little messy, so it'd be nice if I there was a tidier way.

+4  A: 

You can use the property Type.IsPrimitive, but be carefull because there are some types that we can think that are primitives, but they aren´t, for example Decimal and String.

Edit 1: Added sample code

Here is a sample code:

if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
{
    // Is Primitive, or Decimal, or String
}

Edit 2: As @SLaks comments, there are other types that maybe you want to treath as primitives, too. I think that you´ll have to add this variations one by one.

Javier Morillo
And perhaps `DateTime`, `TimeSpan`, and `DateTimeOffset`.
SLaks
Mmmm... yes, you are right. I think we´ll have to add some more possibilities
Javier Morillo
You need to use the logical or (`||`), not the bitwise or (`|`).
SLaks
Why the bitwise or?
Motti
ups! true! thanks, edited.
Javier Morillo
I should test the code in and IDE before writing here, hehe =P
Javier Morillo
Or in LINQPad...
SLaks
Mmmm... I´ve heard about LINQPad, for test LINQ queries, I works to test code too? definitely I´ll try it. thanks
Javier Morillo
@SLaks, I didn't notice the `|` - can you explain why I have to use logical instead of bitwise? - thanks
DaveDev
You did´n notice because I edited my post. I had a mistake, I used | instead or ||. Now is right.
Javier Morillo
+2  A: 

Assuming you have a function signature like this:

void foo<T>() 

You could add a generic constraint to allow value types only:

void foo<T>() where T : struct

Notice that this allows not only primitive types for T, but any value type.

eWolf
+2  A: 

I just found this question while looking for a similar solution, and thought you might be interested in the following approach using System.TypeCode and System.Convert.

It is easy to serialize any type that is mapped to a System.TypeCode other than System.TypeCode.Object, so you could do:

object PropertyValue = ...
if(Convert.GetTypeCode(PropertyValue) != TypeCode.Object)
{
    string StringValue = Convert.ToString(PropertyValue);
    ...
}

The advantage with this approach is you don't have to name every other acceptable non-primitive type. You could also modify the above code slightly to handle any type that implements IConvertible.

Michael Petito