2017-07-29 5 views
0

Ich habe den folgenden Code, Nur Unterschied ist, wie es Daten gruppiert, gibt es eine Möglichkeit, dies in eine Logik durch die Übergabe von Gruppe durch Argumente, So kann der doppelte Code entfernt werden.Wie schreibe ich generische Gruppe von

public interface IStackChartData 
{ 
    IReadOnlyCollection<StackChartData> GetDetails(StackChartSetting chartSetting); 
} 

public class DailyStack : IStackChartData 
{ 
    public IReadOnlyCollection<StackChartData> GetDetails(StackChartSetting chartSetting) 
    { 
     return chartSetting.StackChartDataPoints.GroupBy(x => new { x.DataTime.Hour, x.RateId }) 
                 .OrderBy(x => x.Key.RateId).Select(cl => new StackChartData(
                      cl.Key.RateId, 
                      cl.Key.Hour.ToString(CultureInfo.CurrentCulture), 
                      cl.Sum(c => Convert.ToDecimal(c.YData)), 
                      chartSetting.GetColorCode(cl.Key.RateId))).ToList(); 
    } 
} 

public class MonthlyStack : IStackChartData 
{ 
    public IReadOnlyCollection<StackChartData> GetDetails(StackChartSetting chartSetting) 
    { 
     return chartSetting.StackChartDataPoints.GroupBy(x => new { x.DataTime.Date, x.RateId }) 
            .OrderBy(x => x.Key.RateId).Select(cl => new StackChartData(
                    cl.Key.RateId, 
                    cl.Key.Date.Day.ToString(CultureInfo.CurrentCulture), 
                    cl.Sum(c => Convert.ToDecimal(c.YData)), 
                    chartSetting.GetColorCode(cl.Key.RateId))).ToList(); 
    } 
} 

public class YearlyStack : IStackChartData 
{ 
    public IReadOnlyCollection<StackChartData> GetDetails(StackChartSetting chartSetting) 
    { 
     return chartSetting.StackChartDataPoints.GroupBy(x => new { x.DataTime.Month, x.RateId }) 
             .OrderBy(x => x.Key.RateId).Select(cl => new StackChartData(
                        cl.Key.RateId, 
                        cl.Key.Month.ToString(CultureInfo.CurrentCulture), 
                        cl.Sum(c => Convert.ToDecimal(c.YData)), 
                        chartSetting.GetColorCode(cl.Key.RateId))).ToList(); 
    } 
} 

Antwort

1

x.DataTime Unter der Annahme ist ein DateTime, das einzige, was anders zwischen den Implementierungen ist, dass Sie möglicherweise ein int Month haben, int Hour oder DateTime Date als Zeiteinheit. Sie müssen diese kultursensitive Konvertierung aufrufen, die praktischerweise Teil einer Schnittstelle ist, IConvertible. So können Sie mit einem Func eine static Methode schreiben, dieses Stück von Daten wählen:

internal static IReadOnlyCollection<StackChartData> GetDetails(StackChartSetting chartSetting, Func<DateTime, IConvertible> selector) 
{ 
    return chartSetting.StackChartDataPoints.GroupBy(x => new { TimeUnit=selector(x.DataTime), x.RateId }) 
                .OrderBy(x => x.Key.RateId).Select(cl => new StackChartData(
                     cl.Key.RateId, 
                     cl.Key.TimeUnit.ToString(CultureInfo.CurrentCulture), 
                     cl.Sum(c => Convert.ToDecimal(c.YData)), 
                     chartSetting.GetColorCode(cl.Key.RateId))).ToList(); 
} 

Und dann wird Aufruf einfach:

public class DailyStack : IStackChartData 
{ 
    public IReadOnlyCollection<StackChartData> GetDetails(StackChartSetting chartSetting) 
    { 
     return MyUtilities.GetDetails(chartSetting, x => x.Hour); 
    } 
} 

public class MonthlyStack : IStackChartData 
{ 
    public IReadOnlyCollection<StackChartData> GetDetails(StackChartSetting chartSetting) 
    { 
     return MyUtilities.GetDetails(chartSetting, x => x.Date); 
    } 
} 

public class YearlyStack : IStackChartData 
{ 
    public IReadOnlyCollection<StackChartData> GetDetails(StackChartSetting chartSetting) 
    { 
     return MyUtilities.GetDetails(chartSetting, x => x.Month); 
    } 
} 
Verwandte Themen