2017-07-29 15 views
0

私は以下のコードを持っています。違いはデータをグループ化する方法です。引数でグループを渡すことでこれを1つのロジックにする方法はありますか?一般的なグループを書く方法

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

答えて

1

x.DataTimeDateTimeであると仮定すると、あなたの実装の間で異なる唯一のことは、あなたが時間のあなたのユニットとしてint Monthint Hour、またはDateTime Dateを持っているかもしれないということです。その文化に敏感な変換を呼び出す必要があります。これは便利にはインターフェースの一部で、IConvertibleです。ですから、データのこの作品を選択するためにFuncで1つのstaticメソッドを書くことができます。

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

そして、呼び出しが簡単になる:

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); 
    } 
} 
関連する問題