I have the following method in a class I am using for pagination in my app:
public static PagedList<T> ToPagedList(IEnumerable<T> source, int pageNumber, int pageSize)
{
var count = source.Count();
var items = source
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize).ToList();
return new PagedList<T>(items, count, pageNumber, pageSize);
}
In this method I am passing in a collection of generic objects as IEnumerable<T> source
which regardless of type will always have an Id field. What I'd like to do is pull out all of the Ids for these objects and store them in a list to be passed into my PagedList constructor. Is this possible?
Yes it is possible. You can use Reflection to get the value of a property.
item.GetType().GetProperty("Id").GetValue(item, null);
Edit: Respond to @CoolBots' comment
In case Id
is a field, you can use GetField
instead of GetProperty
item.GetType().GetField("Id").GetValue(item, null);
but if the item doesn't have the "Id" property, this code will fail, so remember to check for null.
the best way would be create an interface
public interface IBaseClass{
public int Id {get; set;}
}
in this case you could change method header
static PagedList<T> ToPagedList<T>(IEnumerable<T> source, int pageNumber, int pageSize)
where T : IBaseClass
and ids
var ids=items.Select(i => i.Id ).ToList();
An interface would be the best way, but you specifically said "field" and interfaces cannot contain fields.
You could get around this limitation with an abstract base class, but you cannot have multiple base classes on a single class (if applicable).
...All of this assumes that you have the ability to modify those classes.
Another way to do this would be:
public static PagedList<T> ToPagedList<T>(IEnumerable<T> source, int pageNumber, int pageSize)
{
var count = source.Count();
var items = source
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize).ToList();
var ids = items
.Select(i => ((dynamic)i).Id) // field is **always** named "Id"
.Cast<int>() // its type is **always** int
.ToList();
return new PagedList<T>(items, count, pageNumber, pageSize/*, ids*/); // pass ids
}
This assumes the field in question is named "Id", and it is an int
.
Adjust accordingly and handle potential errors.
I think I originally misunderstood the question, the comment by @Dusan caused me to reevaluate and update the code.