Вы можете написать универсальный метод расширения, который будет обрабатывать многие случаи. Мясо самой функции - одна строка.
/// <summary>
/// Compares both lists to see if any item in the enumerable
/// equals any item in the other enumerable.
/// </summary>
public static bool AnyItem<T>(this IEnumerable<T> source, IEnumerable<T> other, IEqualityComparer<T> comparer = null)
{
return (comparer == null ? source.Intersect(other) : source.Intersect(other, comparer)).Any();
}
Старше, менее эффективный ответ
public static bool AnyItem<T>(this IEnumerable<T> source, IEnumerable<T> other)
{
return source.Any(s => other.Any(o => EqualityComparer<T>.Default.Equals(s, o)));
}
Я думаю это также более эффективно, чем текущий ответ (Это не так). Мне бы пришлось проверить, стоит ли покупать EqualityComparer, но я хочу в этом сомневаться.
Вы также можете расширить эту функцию, чтобы принимать выражение, которое будет оценивать, какие свойства сравнивать для перечислимых объектов, содержащих объекты.
public static bool AnyItem<T, TResult>(
this IEnumerable<T> source,
IEnumerable<T> other,
Expression<Func<T, TResult>> compareProperty = null)
{
if (compareProperty == null)
{
return source.Any(s => other.Any(o => EqualityComparer<T>.Default.Equals(s, o)));
}
return source.Any(s => other.Any(o =>
EqualityComparer<TResult>.Default.Equals(
s.GetPropertyValue(compareProperty),
o.GetPropertyValue(compareProperty))));
}
public static TValue GetPropertyValue<TTarget, TValue>(
this TTarget target, Expression<Func<TTarget, TValue>> memberLamda)
{
var memberSelectorExpression = memberLamda.Body as MemberExpression;
var property = memberSelectorExpression?.Member as PropertyInfo;
return (TValue)property?.GetValue(target);
}