C# 将linq属性选择器添加到表达式

C# 将linq属性选择器添加到表达式,c#,.net,linq,collections,C#,.net,Linq,Collections,我在Linq中有以下表达式: public static IEnumerable<T> NextDistinct<T>(this IEnumerable<T> items) { T previous = default(T); bool first = true; foreach(T item in items) { if (first || !Equals(previous, item))

我在Linq中有以下表达式:

public static IEnumerable<T> NextDistinct<T>(this IEnumerable<T> items) 
{
    T previous = default(T);
    bool first = true;
    foreach(T item in items)
    {
        if (first || !Equals(previous, item)) 
        {
            first = false;
            previous = item;
            yield return item;
        }
    }
} 
我尝试过,但选择键无法正常工作:

public static IEnumerable<TSource> NextDistinct<TSource, TKey>(this IEnumerable<TSource> source,
            Func<TSource, TKey> keySelector)
        {
            TSource previous = default(TSource);
            bool first = true;
            foreach (TSource item in source)
            {
                if (first || !Equals(previous, item))
                {
                    first = false;
                    previous = item;
                    yield return item;
                }                
            }
        }
预期结果:

365 05/09/2015 02:30:31 p.m.
370 11/10/2015 04:19:37 p.m.
369.59  11/10/2015 04:19:54 p.m.
365 11/10/2015 04:20:05 p.m.

您只需将
TSource previousKey
替换为
TKey previousKey
,并将其与当前项目键进行比较(两者都是使用传递的选择器提取的)。另外,允许为两个函数选择性地指定一个比较器也是很好的。所讨论的功能可能是这样的

public static IEnumerable<TSource> NextDistinct<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IEqualityComparer<TKey> keyComparer = null)
{
    if (source == null) throw new ArgumentNullException("source");
    if (keySelector == null) throw new ArgumentNullException("keySelector");
    if (keyComparer == null) keyComparer = EqualityComparer<TKey>.Default;
    var previousKey = default(TKey);
    bool first = true;
    foreach (TSource item in source)
    {
        var itemKey = keySelector(item);
        if (first || !keyComparer.Equals(previousKey, itemKey))
        {
            yield return item;
            first = false;
            previousKey = itemKey;
        }
    }
}
公共静态IEnumerable下一个目标(
这是一个数不清的来源,
Func键选择器,
IEqualityComparer键比较器=空)
{
如果(source==null)抛出新的ArgumentNullException(“source”);
如果(keySelector==null)抛出新的ArgumentNullException(“keySelector”);
如果(keyComparer==null)keyComparer=EqualityComparer.Default;
var previousKey=默认值(TKey);
bool first=true;
foreach(源中的TSource项)
{
var itemKey=键选择器(项);
if(第一个| |!keyComparer.Equals(previousKey,itemKey))
{
收益回报项目;
第一个=假;
previousKey=itemKey;
}
}
}

是的,您的函数定义似乎正确,但您必须使用keySelector参数。请告诉我如何使用,我只更改了accept属性选择器的函数定义,但不知道如何在函数内部使用它。keySelector现在是一个您可以调用的函数。它接受tsource类型的参数并返回tkey类型的对象。我尝试过:foreach(source.Select(keySelector)中的tsource项)请查看我更新的问题,如果我只在查询中选择一列,效果很好,但我需要选择两列双日期时间类型,因此问题就从这里开始,因为所有的日期都不一样,所以我用了一个selectorPerfect谢谢,这正是我需要的。
365 05/09/2015 02:30:31 p.m.
370 11/10/2015 04:19:37 p.m.
369.59  11/10/2015 04:19:54 p.m.
365 11/10/2015 04:20:05 p.m.
365 11/10/2015 04:20:58 p.m.
365 11/10/2015 04:33:22 p.m.
365 05/09/2015 02:30:31 p.m.
370 11/10/2015 04:19:37 p.m.
369.59  11/10/2015 04:19:54 p.m.
365 11/10/2015 04:20:05 p.m.
public static IEnumerable<TSource> NextDistinct<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IEqualityComparer<TKey> keyComparer = null)
{
    if (source == null) throw new ArgumentNullException("source");
    if (keySelector == null) throw new ArgumentNullException("keySelector");
    if (keyComparer == null) keyComparer = EqualityComparer<TKey>.Default;
    var previousKey = default(TKey);
    bool first = true;
    foreach (TSource item in source)
    {
        var itemKey = keySelector(item);
        if (first || !keyComparer.Equals(previousKey, itemKey))
        {
            yield return item;
            first = false;
            previousKey = itemKey;
        }
    }
}