Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make 1 generic method out of these 2 linq statements?

Tags:

c#

linq

I have 2 linq statements - currently in the middle of a switch block. The statements are below.

pwStartTime = lender.ApplicationWindows
.Where(w => w.Name == pwPeriod && w.EndTime.TimeOfDay > dateToCheck.TimeOfDay)
.Select(w => w.StartTime)
.FirstOrDefault();


pwStartTime = lender.TransferWindows
.Where(w => w.Name == pwPeriod && w.EndTime.TimeOfDay > dateToCheck.TimeOfDay)
.Select(w => w.StartTime)
.FirstOrDefault();

As you can see the only difference is that they refer to two different properties of "lender", however, all the elements used in the linq query are identical in "ApplicationWindows" and "TransferWindows", although they are not the same objects and each does contain other unique properties.

So, it it possible to return w.StartDate via one generic method?

Thanks in advance.

// Here's the 2 classes

public class ApplicationWindow
{
    public string Name { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}

public class TransferWindow
{
    public string Name { get; set; }

    public DateTime StartTime { get; set; }

    public DateTime EndTime { get; set; }

    [XmlIgnore]
    public TimeSpan Cycle { get; set; }

    [Browsable(false)]
    [XmlElement("Cycle")]
    public string CycleString
    {
        get { return XmlConvert.ToString(Cycle); }
        set { Cycle = value.IsNullOrEmpty() ? TimeSpan.Zero : XmlConvert.ToTimeSpan(value); }
    }
}
like image 625
dotnetnoob Avatar asked Apr 18 '13 07:04

dotnetnoob


2 Answers

If ApplicationWindows and TransferWindows implement a common interface then you can do the following;

public DateTime GetStartTime(IEnumerable<IWindow> windows, string pwPeriod, TimeSpan timeOfDay)
{
    return windows.Where(w => w.Name == pwPeriod && w.EndTime.TimeOfDay > timeOfDay)
        .Select(w => w.StartTime)
        .FirstOrDefault();
}

UPDATE

If you are using LINQ To SQL then you can have these implement an interface by creating a partial class with the same name (and in the same namespace) as the two Window classes, saying that this implements the interface.

I believe this should work, although I haven't done this in a while and I did it with VB.NET.

like image 166
Sam Jenkins Avatar answered Oct 03 '22 15:10

Sam Jenkins


An example of what you can do with interfaces:

pwStartTime = lender.ApplicationWindows.FirstOrDefaultDateTime(pwPeriod, dateToCheck);
pwStartTime = lender.TransferWindows.FirstOrDefaultDateTime(pwPeriod, dateToCheck);

public interface IWindow
{
    string Name { get; }
    public DateTime StartTime { get; }
    public DateTime EndTime { get; }
}

public class ApplicationWindow : IWindow
{
    public string Name { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}

public class TransferWindow : IWindow
{
    public string Name { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}

public static class IWindowExt
{
    public static DateTime FirstOrDefaultDateTime(this IEnumerable<IWindow> windows, string pwPeriod, DateTime dateToCheck)
    {
        return windows
                .Where(w => w.Name == pwPeriod && w.EndTime.TimeOfDay > dateToCheck.TimeOfDay)
                .Select(w => w.StartTime)
                .FirstOrDefault();
    }
}

When you have method which aim at one interface, the prettier solution is to create extension method associated.

like image 39
Cyril Gandon Avatar answered Oct 03 '22 15:10

Cyril Gandon