У меня есть кусок кода, который просто сравнивает две коллекции и возвращает все элементы из одного списка, который не принадлежит другому.Немедленное окно и среда выполнения, дающая разные результаты для одного оператора LINQ
Поскольку эти два списка содержат объекты, которые не являются справедливыми по ссылке, у меня есть простой IEquatable
, который сравнивает объекты с их идентификаторами.
код Я бегу следующим образом:
private PreferenceDefinition[] FindUserPreferencesToAdd(PreferenceDefinition[] newDefinitions, PreferenceDefinition[] oldDefinitions)
{
//Get the newly selected definitions
var newPreferences = newDefinitions.Where(def => def.IsSelected);
//Get all new definitions that don't exist in the old list
var preferencesToAdd = newPreferences.Where(def => !oldDefinitions.Contains(def)).ToArray();
return preferencesToAdd;
}
Результат preferencesToAdd
дает мне точно такой же список в newPreferences
, несмотря на обеспечение того, чтобы намеренно newDefinitions
содержит дополнительный элемент, который был выбран. Если я перейду в 7 новых предпочтений, он вернет 7 предпочтений для «добавления» - неправильной реализации.
Однако, когда я бегу точно такое же заявление LINQ в Immediate Window, когда я достиг точки останова на возвращение, он дает мне:
newPreferences.Where(def => !oldDefinitions.Contains(def)).ToArray();
{App1Test.PreferenceDefinition[1]}
[0]: {App1Test.PreferenceDefinition}
Это содержит единственный результат, который должен быть добавлен.
Зачем нужно немедленно отображать верный результат, но код времени выполнения не будет? Я попытался запустить этот оператор в непосредственном окне до и после выполнения запроса LINQ для выполнения, чтобы убедиться, что это не порядок операций, но это не имело никакого значения.
Edit:
Я нашел решение моей проблемы, заменив второе заявление LINQ с:
var preferencesToAdd = newPreferences.Where(d => !oldDefinitions.Any(def => def.Equals(d))).ToArray();
Однако я не понимаю, почему оригинал не работает. У меня очень похожий сценарий, который делает противоположное тому, что я пытаюсь достичь здесь (найти элементы для удаления), и он отлично работает. Я что-то упускаю?
Edit 2:
Этот код, даже без IEquatable, работал отлично:
private PreferenceDefinition[] FindUserPreferencesToDelete(PreferenceDefinition[] newDefinitions, PreferenceDefinition[] oldDefinitions)
{
//Get the newly selected definitions
var newPreferences = newDefinitions.Where(def => def.IsSelected);
//Get all old definitions that don't exist in this new list
var preferencesToDelete = oldDefinitions.Where(def => !newPreferences.Contains(def));
return preferencesToDelete.ToArray();
}
Почему это будет работать хорошо, но первый метод не будет?
Показать свою реализацию IEquatabe. –
@HamletHakobyan Это просто 'public bool Equals (PreferenceDefinition other) { return this.Id == other.Id; } ' – plusheen
@plusheen: Просто в стороне, но ваша реализация' Equals' должна изящно иметь дело с возможностью 'other' быть' null'. – sstan