Let's make this a little bit more generic, so you can use it as any other LINQ method. After that we can specialize in a method for your class
LINQ is defined using extension methods. If you are not familiar how to create an extension method, read Extension Methods Demystified
For the examples I use the following class. Any class with two DateTime properties will do
class PurchasedProduct
{
public string Name {get; set;}
public DateTime PurchaseDate {get; set;}
public DateTime ExpiryDate {get; set;}
}
Our goal is a method that does the following:
TimeSpan maxTime = TimeSpan.FromDays(45);
IEnumerable<PurchardProduct> purchasedProducts = ...
IEnumerable<PurchasedProducts> almostExpiredProducts =
purchasedProducts.WhereAlmostExpired(maxTime);
Here we go!
First a method that says whether a class with two DataTimes is near expiry date:
public static bool IsWithinTimeSpan<T>(this T source,
Func<T, DateTime> startDateSelector,
Func<T, DateTime> endDateSelector,
TimeSpan maxTime)
{
return startDateSelector(source) - endDateSelector(source) < maxTime;
}
In words: take your source. Use the startDateSelector to extract the startDate; Use the endDateSelector to extract the endDate. Subtract these two DateTimes, and return true if the result is less than maxTime;
Usage:
PurchasedProduct purchasedProduct = new PurchasedProduct {...};
bool productNearExpiryDate = product.IsWithinTimeSpan(maxTime);
Well, if we can do this with one T, we can do this with a sequence of T:
public static IEnumerable<T> WhereWithinTimeSpan<T>(
this IEnumerable<T> source,
Func<T, DateTime> startDateSelector,
Func<T, DateTime> expiryDateSelector,
TimeSpan maxTime)
{
return source.Where(t => t.IsWithinTimeSpan(
startDateSelector, expiryDateSelector, maxTime));
}
Well that was easy, only one line of code!
This looks very much like our goal, only one more function to go to make it like the method you want:
public static IEnumerable<PurchasedProduct> WhereAlmostExpired(
this IEnumerable<PurchasedProduct> purchasedProducts,
TimeSpan maxTime)
{
return purchasedProducts.WhereWithinTimeSpan(
product => product.PurchaseDate,
product => product.ExpiryDate,
maxTime);
}
Again, only one line of code! Of course, if your sequence of items is not IEnumerable<PurchasedProduct>
, but for instance IEnumerable<MyClass>
, change this one line of code accordingly.
So now we are able to use it for your problem:
TimeSpan maxTime = TimeSpan.FromDays(45);
IEnumerable<MyClass> myObjects = ...
IEnumerable<MyClass> almostExpiredObjects = myObjects.WhereAlmostExpired(maxTime);
Simple comme bonjour!
One final remark: if you are not certain that startTime is smaller then endTime, don't forget to use absolute value before your comparison