由於Tormod說,最好的辦法是使用DistinctBy()
實現。
(尤其是看Tormod的實現,你會看到它實際上是相同的,如下DistinctByImpl()方法,所以這個答案應該被視爲是他的擴展。)
如果使用DistinctBy()時,溶液變得簡單:
var uniques = list.DistinctBy(item => item.LinkId);
一個好的實施DistinctBy()
可以在Jon Skeet's MoreLinq
library這也是available on NuGet找到。
舉個例子,下面是一個使用MoreLinq的DistinctBy()實現副本的實現。不要使用此代碼 - 使用NuGet下載原始註釋代碼。
using System;
using System.Linq;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
public static void Main(string[] args)
{
List<Test> list = new List<Test>
{
new Test(1, 1),
new Test(2, 1),
new Test(3, 2),
new Test(4, 2)
};
var uniques = list.DistinctBy(item => item.LinkId);
foreach (var item in uniques)
{
Console.WriteLine(item);
}
}
}
public class Test
{
public Test(int linkSysId, int linkId)
{
LinkSysId = linkSysId;
LinkId = linkId;
}
public override string ToString()
{
return string.Format("LinkSysId = {0}, LinkId = {1}", LinkSysId, LinkId);
}
public int LinkSysId;
public int LinkId;
}
static class EnumerableExt
{
public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return source.DistinctBy(keySelector, null);
}
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
if (source == null) throw new ArgumentNullException("source");
if (keySelector == null) throw new ArgumentNullException("keySelector");
return DistinctByImpl(source, keySelector, comparer);
}
private static IEnumerable<TSource> DistinctByImpl<TSource, TKey>(IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
var knownKeys = new HashSet<TKey>(comparer);
return source.Where(element => knownKeys.Add(keySelector(element)));
}
}
}
有趣的是,標題聽起來像一切順利。 – 2013-03-21 13:36:13
@GertArnold我真的很驚訝,因爲它會在迭代整個列表之後進行刪除。我認爲這種邏輯的原因是在迭代中避免萬聖節問題。 – Alex 2013-03-21 13:39:40
請注意,'RemoveAll'根本不是LINQ的一部分。這是'List'的方法,而不是'Enumerable'。 – Servy 2013-03-21 13:55:23