Ответ 1
Вы можете написать общий метод расширения, который обрабатывал бы многие случаи. Мясо самой функции - одна линия.
/// <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)));
}
Я думаю, что это также более эффективно, чем текущий ответ (It not). Мне нужно будет проверить, дорого ли стоит 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);
}