dotnetnoob
dotnetnoob

Reputation: 11330

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

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); }
    }
}

Upvotes: 5

Views: 153

Answers (3)

Ant P
Ant P

Reputation: 25221

Why not create an interface or abstract base class for TransferWindow and ApplicationWindow, defining the common properties? Then you can do something like this (assuming that lender.TransferWindows and lender.ApplicationWindows are lists of their respective classes - if not, modify method signature as appropriate):

public DateTime GetStartTime(IList<Window> windows, DateTime dateToCheck, string pwPeriod)
{
    return windows
    .Where(w => w.Name == pwPeriod && w.EndTime.TimeOfDay > dateToCheck.TimeOfDay)
    .Select(w => w.StartTime)
    .FirstOrDefault();
} 

Upvotes: 1

Cyril Gandon
Cyril Gandon

Reputation: 17048

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.

Upvotes: 3

Sam Jenkins
Sam Jenkins

Reputation: 1314

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.

Upvotes: 5

Related Questions