-2

I have this method that I want to write:

public static IQueryable<TSource> CutTo<TSource>(this IQueryable<TSource> source, Func<int> func)
{
    int index = func();
    // here I can write something for all types or switch all
    // the types and write code for every type
}

What is the easiest way to code this for all TSource types?

Edit: Black Bear writes that this already works for all types but this is not true. Mono writes like this:

public static IQueryable<TSource> Where<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
{
    Check.SourceAndPredicate (source, predicate);

    return source.Provider.CreateQuery<TSource> (
        StaticCall (
            MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
            source.Expression,
            Expression.Quote (predicate)));
}
Beta
  • 87
  • 7

1 Answers1

1

First solution (cleaner one)

Will work only with types that implement specific interface

Create interface IHaveId

public interface IHaveId
{
    int Id { get; set; }
}

Then every model with Id propery should implement IHaveId. Example

public class Post : IHaveId
{
    int Id { get; set; }
    string Title { get; set; }
    string Content { get; set; }
}

And then write your CutTo method like:

public static IQueryable<T> CutTo<T>(this IQueryable<T> source, Func<int> func)
    where T: IHaveId
{
    int index = func();
    return source.Where(x => x.Id == index);
}

The idea is that every implementation of IHaveId will have int property called Id and then you can limit CutTo method to work only with implementations of IHaveId and use their Id property.

Second solution (uglier)

Will work with any type that keeps Entity Framework convention for naming primary keys

  1. Use reflection over typeof(TSource) to find property named Id or typeof(TSource).Name + "Id"
  2. Again with reflection build Expression<Func<TSource, int>> and apply it in IQueryable<T> source with Where clause.
Community
  • 1
  • 1
Nikolay Kostov
  • 16,433
  • 23
  • 85
  • 123