C# 返回LINQ列表相隔X分钟

C# 返回LINQ列表相隔X分钟,c#,linq,datetime,grouping,C#,Linq,Datetime,Grouping,之前解决了一个类似的问题,我尝试使用他们的代码,但将其转换为通用函数,例如 我正在尝试构建一个函数,该函数将返回始终相隔2小时的对象列表。如果列表DateTime字段被称为“Time”,则还必须将DateTime属性名称传递到此函数,即“Time” 它已经可以工作了,但是,它并不是完美的。我怀疑分组中的计算需要调整。我试过: ((DateTime)property.GetValue(x)).Hour % 2 ((DateTime)property.GetValue(x)).Hour - 2

之前解决了一个类似的问题,我尝试使用他们的代码,但将其转换为通用函数,例如

我正在尝试构建一个函数,该函数将返回始终相隔2小时的对象列表。如果列表DateTime字段被称为“Time”,则还必须将DateTime属性名称传递到此函数,即“Time”

它已经可以工作了,但是,它并不是完美的。我怀疑分组中的计算需要调整。我试过:

((DateTime)property.GetValue(x)).Hour % 2

((DateTime)property.GetValue(x)).Hour - 2

((DateTime)property.GetValue(x)).Hour * 2
它们要么不返回预期结果,要么引发异常:

"Hour, Minute, and Second parameters describe an un-representable DateTime."
这就是它目前的样子:

public static class ICollectionExtensions
{
    public static IEnumerable<T> GetByHoursApart<T>(this IEnumerable<T> source, string dateTimePropertyName)
    {
        if (source == null)
        {
            throw new NullReferenceException("source");
        }

        Type myType = typeof(T);
        IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
        var property = props.FirstOrDefault(x => x.Name == dateTimePropertyName);

        if (property.PropertyType != typeof(DateTime))
        {
            throw new InvalidCastException(dateTimePropertyName);
        }

        return source.GroupBy(x =>
        {
            return 
                new DateTime(((DateTime)property.GetValue(x)).Year, 
                            ((DateTime)property.GetValue(x)).Month, 
                            ((DateTime)property.GetValue(x)).Day, 
                            ((DateTime)property.GetValue(x)).Hour / 2, 
                            0, 
                            0);

        }).Select(x => (T)x.First()).Distinct().ToList();
    }
}
公共静态类ICollectionExtensions
{
公共静态IEnumerable GetByHoursPart(此IEnumerable源,字符串dateTimePropertyName)
{
if(source==null)
{
抛出新的NullReferenceException(“源”);
}
类型myType=类型(T);
IList props=新列表(myType.GetProperties());
var property=props.FirstOrDefault(x=>x.Name==dateTimePropertyName);
if(property.PropertyType!=typeof(DateTime))
{
抛出新的InvalidCastException(dateTimePropertyName);
}
返回source.GroupBy(x=>
{
返回
新的DateTime(((DateTime)属性.GetValue(x)).Year,
((DateTime)property.GetValue(x)).Month,
((DateTime)property.GetValue(x)).Day,
((DateTime)property.GetValue(x)).Hour/2,
0, 
0);
}).Select(x=>(T)x.First()).Distinct().ToList();
}
}
编辑:

我现在也尝试了以下类似的结果集

public static class ICollectionExtensions
{
    public static IEnumerable<T> GetByHoursApart<T>(this IEnumerable<T> source, int hoursApart, string dateTimePropertyName)
    {
        if (source == null)
        {
            throw new NullReferenceException("source");
        }

        Type myType = typeof(T);
        IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
        var property = props.FirstOrDefault(x => x.Name == dateTimePropertyName);

        if (property.PropertyType != typeof(DateTime))
        {
            throw new InvalidCastException(dateTimePropertyName);
        }

        return source.GroupBy(x =>
        {
            return
                new DateTime(((DateTime)property.GetValue(x)).Year,
                            ((DateTime)property.GetValue(x)).Month,
                            ((DateTime)property.GetValue(x)).Day,
                            ((DateTime)property.GetValue(x)).AddHours(-((DateTime)property.GetValue(x)).Hour % hoursApart).Hour,
                            ((DateTime)property.GetValue(x)).AddMinutes(-((DateTime)property.GetValue(x)).Minute).Minute,
                            ((DateTime)property.GetValue(x)).AddSeconds(-((DateTime)property.GetValue(x)).Second).Second);

        }).Select(x => (T)x.First()).Distinct().ToList();
    }
}
公共静态类ICollectionExtensions
{
公共静态IEnumerable GetByHoursPart(此IEnumerable源,int HoursPart,字符串dateTimePropertyName)
{
if(source==null)
{
抛出新的NullReferenceException(“源”);
}
类型myType=类型(T);
IList props=新列表(myType.GetProperties());
var property=props.FirstOrDefault(x=>x.Name==dateTimePropertyName);
if(property.PropertyType!=typeof(DateTime))
{
抛出新的InvalidCastException(dateTimePropertyName);
}
返回source.GroupBy(x=>
{
返回
新的DateTime(((DateTime)属性.GetValue(x)).Year,
((DateTime)property.GetValue(x)).Month,
((DateTime)property.GetValue(x)).Day,
((DateTime)属性.GetValue(x)).AddHours(-(DateTime)属性.GetValue(x)).Hours%HoursPart.Hours,
((DateTime)属性.GetValue(x)).AddMinutes(((DateTime)属性.GetValue(x)).Minutes,
((DateTime)property.GetValue(x)).AddSeconds(-(DateTime)property.GetValue(x)).Second);
}).Select(x=>(T)x.First()).Distinct().ToList();
}
}
已解决:

我在过滤组中找到了解决方案。确保时间与组的小时数相同,而不是允许驻留在2小时组内的任何值为真。以下是完成的代码:

public static class ICollectionExtensions
{
    public static IEnumerable<T> GetByHoursApart<T>(this IEnumerable<T> source, int hoursApart, string dateTimePropertyName)
    {
        if (source == null)
        {
            throw new NullReferenceException("source");
        }

        Type myType = typeof(T);
        IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
        var property = props.FirstOrDefault(x => x.Name == dateTimePropertyName);

        if (property.PropertyType != typeof(DateTime))
        {
            throw new InvalidCastException(dateTimePropertyName);
        }

        return source.GroupBy(x =>
        {
            return
            new DateTime(((DateTime)property.GetValue(x)).Year,
                        ((DateTime)property.GetValue(x)).Month,
                        ((DateTime)property.GetValue(x)).Day,
                        ((DateTime)property.GetValue(x)).AddHours(-((DateTime)property.GetValue(x)).Hour % hoursApart).Hour,
                        ((DateTime)property.GetValue(x)).AddMinutes(-((DateTime)property.GetValue(x)).Minute).Minute,
                        ((DateTime)property.GetValue(x)).AddSeconds(-((DateTime)property.GetValue(x)).Second).Second);

        }).Where(x => x.Key.Hour == ((DateTime)property.GetValue(x.First())).Hour).Select(x => (T)x.First()).Distinct().ToList();
    }
}
公共静态类ICollectionExtensions
{
公共静态IEnumerable GetByHoursPart(此IEnumerable源,int HoursPart,字符串dateTimePropertyName)
{
if(source==null)
{
抛出新的NullReferenceException(“源”);
}
类型myType=类型(T);
IList props=新列表(myType.GetProperties());
var property=props.FirstOrDefault(x=>x.Name==dateTimePropertyName);
if(property.PropertyType!=typeof(DateTime))
{
抛出新的InvalidCastException(dateTimePropertyName);
}
返回source.GroupBy(x=>
{
返回
新的DateTime(((DateTime)属性.GetValue(x)).Year,
((DateTime)property.GetValue(x)).Month,
((DateTime)property.GetValue(x)).Day,
((DateTime)属性.GetValue(x)).AddHours(-(DateTime)属性.GetValue(x)).Hours%HoursPart.Hours,
((DateTime)属性.GetValue(x)).AddMinutes(((DateTime)属性.GetValue(x)).Minutes,
((DateTime)property.GetValue(x)).AddSeconds(-(DateTime)property.GetValue(x)).Second);
}).Where(x=>x.Key.Hour==((DateTime)property.GetValue(x.First())).Hour)。选择(x=>(T)x.First()).Distinct().ToList();
}
}

也许你的期望是错误的。如果源为空或只有一个元素,则最终将只有零个或一个组。最好提供一些示例输入。现在使用除法,你按小时分组,得出相同的结果,然后除以2。所以(4,5)是一组,(6,7)是一组等等。到目前为止看起来不错。最后的distinct似乎是无用的,如果它们在Datetimeproperty上不同,那么它们就不可能相等。