employees
とシーケンスが同じタイプのオブジェクトである場合contacts
(または両方がのように同じタイプから継承する場合Contact
)、EqualityComparer
インスタンスを作成できます。
public class ContactComparer : EqualityComparer<Contact>
{
public override bool Equals(Contact x, Contact y)
{
if (ReferenceEquals(x, y)) return true;
return x != null && y != null && x.ContactId == y.ContactId;
}
public override int GetHashCode(Contact obj)
{
if (obj == null) throw new ArgumentNullException("obj");
// assuming string
return (obj.ContactId ?? "").GetHashCode();
}
}
これにより、これを実行できるため、結果を直接返すだけで、二重クエリを実行する必要がなくなります。
var contactsNotEmployees = myContacts.Except(employees, new ContactComparer()).ToList();
更新:コメントが示すようにContactとEmployeeが別々のタイプであるため、ContactIdプロパティを使用してインターフェイスを作成し、共通の結合を作成することを検討できます。
または、例外の結果をaにエクスポートしてから、からHashSet
を使用することをお勧めします。これは、O(n)効率であるシーケンスではなく、O(1)効率です。Contains()
HashSet
Contains()
// get hash set of contact-only IDs
var except = new HashSet<int>(contacts
.Select(c => c.ContactId)
.Except(emplopyees.Select(e => e.ContactId)));
// get the objects for those IDs
var others = contacts.Where(c => except.Contains(c.ContactId)).ToList();
Contains()
シーケンスを使用した結果を比較すると、HashSet
Contains()
小さいリスト(15アイテム)の場合は約50%速くなり、長いリストの場合はさらに速くなります。
IEnumerable<T>
とにかく、シーケンス()のContains( )は比較的遅いので、それを捨てるだけです...
私は両方のソリューションの時間を1,000,000回以上繰り返して、次のようにしました。
HashSet With Contains() took: 1429 ms, 0.001429 ms/item.
Sequence With Contains() took: 3386 ms, 0.003386 ms/item.