4

I have a class that looks like this :

public class ObjectA
{
    public ObjectB OneObject { get; set; }

    public List<ObjectC> ManyObject { get; set; }
}

And then a function to read what the class contains and return the type of property :

source = typeof(*some ObjectA*)

var classprops = source.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.PropertyType.IsClass && !x.PropertyType.IsValueType && x.PropertyType.Name != "String");

foreach (var prop in classprops)
{
    var classnamespace = CommonTool.GetNamespaceFromProp(prop);

    if ((prop.PropertyType).Namespace == "System.Collections.Generic")
    {
        string newprop = prop.ToString();
        int start = newprop.IndexOf("[")+1;
        int end = newprop.IndexOf("]");
        newprop = newprop.Substring(start, end-start);
        newprop = string.Format("{0}, Env.Project.Entites", newprop);
        classnamespace = newprop;
    }
    //some code to read attributes on the properties...
}

My problem is what is within the if ((prop.PropertyType).Namespace == "System.Collections.Generic"). It smells.

Any better way to do that?

edit :

A class in the application uses List<int>.
This caused crashes.
It wasn't only smelling bad.

Kraz
  • 6,910
  • 6
  • 42
  • 70
  • Not sure if I understand what you're trying to achieve. Do you just want to pull out the fact that type `ObjectA` leverages types `ObjectB` and `ObjectC`? Beyond that, at the very least you can use [Type.GetGenericArguments](http://msdn.microsoft.com/en-us/library/system.type.getgenericarguments.aspx) to retrieve the type used on the list rather than trying to parse out its `ToString()` representation. – Chris Sinclair Feb 07 '13 at 16:52
  • @Pete : It's indeed really close. However, I never use generic type. – Kraz Feb 07 '13 at 20:33
  • @ChrisSinclair : Yep, that's what I was looking for. Lee's answer uses that too. – Kraz Feb 07 '13 at 20:33

1 Answers1

3

If you want to check if the property is a generic collection, and get the element type, you can check to see if it impelements IEnumerable<T> and get the type T if it does

Type propType = prop.PropertyType;
if (propType.IsGenericType)
{
    Type enumerableType = propType.GetInterfaces().FirstOrDefault(it => it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IEnumerable<>)));
    if(enumerableType != null)
    {
        Type elementType = enumerableType.GetGenericArguments()[0];
    }
}
Lee
  • 142,018
  • 20
  • 234
  • 287