我有一段代码只是比较两个集合,并返回一个列表中不属于另一个列表的所有项目。
由于这两个列表包含的引用并不公平,我有一个简单的IEquatable
来比较ID上的对象。
我正在运行的代码如下:
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语句时,它给了我:
newPreferences.Where(def => !oldDefinitions.Contains(def)).ToArray();
{App1Test.PreferenceDefinition[1]}
[0]: {App1Test.PreferenceDefinition}
这包含应添加的单个结果。
为什么立即窗口会给我正确的结果,但运行时代码不会?我尝试在运行时LINQ查询运行之前和之后在即时窗口中运行此语句,以确保它不是一个操作顺序,但它没有区别。
编辑:
通过将第二个LINQ语句替换为:
,我找到了解决我的问题的方法 var preferencesToAdd = newPreferences.Where(d => !oldDefinitions.Any(def => def.Equals(d))).ToArray();
但是我不明白为什么原版不起作用。我有一个非常类似的场景,它与我试图在这里实现的相反(找到要删除的项目),并且它工作正常。我错过了什么吗?
编辑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();
}
为什么这样可行,但第一种方法不会?
答案 0 :(得分:2)
看看这里:
https://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx
如果您实现IEquatable,您还应该覆盖基础 Object.Equals(Object)和GetHashCode的类实现 它们的行为与IEquatable.Equals的行为一致 方法
您可以明确地推断 == 运算符不受实施 IEquatable ;
的影响因此,等于调用使用您的自定义相等方法,包含在内部使用未被覆盖的 Object.Equals 。
数组实现 ICollection 因此内部使用的包含方法在 IndexOf 的数组中实现,而不使用 EqualityComparer.Default < / strong>试图使用 IEquatable.Equals (如果有的话)。
尝试添加此内容:
public override bool Equals(object obj)
{
var test = obj as Test;
return test == null ? obj.Equals(this) : Equals(test);
}
您可以在此处看到一个简单示例:https://dotnetfiddle.net/C5R4bE