I have to create a method for selecting a firts property from collection with the specified type.
I have created the method like this (I have removed some parts for the brevity):
public static IQueryable<TResult> SelectFirstPropertyWithType<T, TResult>(this IQueryable<T> source)
{
// Get the first property which has the TResult type
var propertyName = typeof(T).GetProperties()
.Where(x => x.PropertyType == typeof(TResult))
.Select(x => x.Name)
.FirstOrDefault();
var parameter = Expression.Parameter(typeof(T));
var body = Expression.Convert(Expression.PropertyOrField(parameter, propertyName), typeof(TResult));
var expression = Expression.Lambda<Func<T, TResult>>(body, parameter);
return source.Select(expression);
}
And I can call this method as:
List<Person> personList = new List<Person>();
// .. initialize personList
personList.AsQueryable()
.SelectFirstPropertyWithType<Person, int>()
.ToList();
Everything works fine.
But, I don't want to set first argument type as Person
, because compiler can infer this argument type fromthe source of the collection. Is there any way to call the method like that:
.SelectFirstPropertyWithType<int>()
The problem is I need T
parameter inside my method, and I don't want to create Func
with reflection in runtime.
Thanks.
C# Generics simply does not allow you to specify a subset of the type parameters. It's all or nothing.
The way to work around this is to write a fluent interface. You break this operation up into a chain of methods.
Now you can call: