tags:

views:

53

answers:

3

For example, let's say I have a method that takes the following as a parameter:

Expression<Func<T, object>> path

How do I determine the type of the 'object' specified in the expression? More specifically, I'd like to determine if it's a collection type (eg. IEnumerable)

A: 
Richard
@Richard: I'm using this to define fetching strategies for a repository, so the "path" expression would be something like entity => entity.Property; I need to determine if that "Property" is a collection type. I hope this helps to clarify.
DanP
@DanP: The `Type` property gives you a `Type` instance, you can then check for implementation of `IEnumerable` (without which a type in .NET isn't really a collection) in the normal way.
Richard
@Richard: this will give me the type of the root object that owns the property; I was interested in the type of the property itself.
DanP
@DanP: You need to look at the `Expression` subtype, not all represent a property (look at the example in the Expression.Type doc -- linked in the A).
Richard
+2  A: 

You're already using generics, so why not go all the way?

void GetMemberType<TArg, TProperty>(Expression<Func<TArg, TProperty>> path)
{
    // Get the member ...
    var member = path.Body as MemberExpression;

    // ... Do whatever you want with the member ...

    // Now get the type
    var memberType = typeof(TProperty);
}
Charles
Type inference will let you omit the two generic type params when you call the method, assuming TArg happens to be a generic type param used by the declaring class - as in `class SomeClass<TArg> { ... }`.
Charles
typeof(IEnumerable).IsAssignableFrom(typeof(TProperty)) gets DanP the rest of the way there.
Kirk Woll
Thanks to Carles and Kirk - this is exactly what I *should* have been doing :)
DanP
I added an alternative method as another answer - and it matches DanP's `Expression<Func<T, object>> path`, as opposed to my more generic `Expression<Func<TArg, TProperty>> path`.
Charles
+1  A: 

Alternatively, you could do something like the following (which is more inline with you generic type arguments):

// Get your expression
// (probably already provided as an arg to one of your methods, I'm willing to bet)
Expression<Func<T, object>> path = ...

var memberExpr = path.Body as MemberExpression;
var member = memberExpr.Member;

Type type;

if (member is FieldInfo)
{
    var field = member as FieldInfo;
    type = field.FieldType;
}

if (member is PropertyInfo)
{
    var property = member as PropertyInfo;
    type = property.PropertyType;
}
Charles
@Charles: thanks for adding this alternative method, good to know if I couldn't use the infered generics for some reason.
DanP