views:

34

answers:

1

We have a DAL that we're using with NHibernate.Search, so classes that need to be indexed are decorated with an attribute Indexed(Index:="ClassName"), and each property that needs to be be indexed has an attribute Field(Index:=Index.Tokenized, Store:=Store.No) . When one wants the index to drill down special objects, there's the attribute IndexedEmbedded()

In order to auto-document our indexation hierarchy, i've built a simple parser that runs through the DAL assembly, picks up any class marked as indexable and gets the properties that are either indexable or whose type is available for drill-down. When the type of the property is declared as available for drill-down, i push this type into the queue and process it too.

The problem is that among the classes you can drill down into, some are themselves contained in IEnumerable generic collections. I'd like to get at the type used for the collection (usually ISet) to parse it too.

So what's the way to get the inner type of a collection?

Private m_TheMysteriousList As ISet(Of ThisClass)
<IndexedEmbedded()> _
Public Overridable Property GetToIt() As ISet(Of ThisClass)
   Get
        Return m_TheMysteriousList
   End Get
   Set(ByVal value As ISet(Of ThisClass))
        m_TheMysteriousList = value
   End Set
End Property

How do i get to ThisClass when i have the PropertyInfo for GetToIt?

+2  A: 

Something like:

public static Type GetEnumerableType(Type type)
{
    if (type == null) throw new ArgumentNullException();
    foreach (Type interfaceType in type.GetInterfaces())
    {
        if (interfaceType.IsGenericType &&
            interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        {
            return interfaceType.GetGenericArguments()[0];
        }
    }
    return null;
}
...
PropertyInfo prop = ...
Type enumerableType = GetEnumerableType(prop.PropertyType);

(I've used IEnumerable<T> here, but it is easily adjusted to suit any other similar interface)

Marc Gravell
Flawless; the GetgenericArguments was indeed where i was looking for the solution, but i wouldn't immediately have had the idea to look for it in interfaces. Thanks
samy