相交在列表之间不起作用
Intersect doesn't work between Lists
我有一个奇怪的问题。
我使用 Visual Studio 并且我正在用 C# 开发一个项目。
我有两个自定义 classes "Attr" 和 "FD" 并且我使用包含它们的对象的列表,例如
List<Attr> attrList = new List<Attr>();
List<FD> fdList = new List<FD>();
所以当我试图找到两个列表的交集时,结果不是我所期望的。为了使它更简单,我尝试 Intersect similar Objects 结果又是错误的。出了什么问题?
这是fd。它是 class FD 的对象。
这是 ff,它也是 FD class 的一个对象。
如您所见,这些对象包含完全相同的值。
方法 GetLeft() returns 包含 class Attr.
对象的列表
所以当我试图找到这两个列表之间的交集时 (fd.GetLeft() 和 ff.GetLeft() ) 结果什么都没有(它应该是一个包含 Attr 对象的列表 "A")。
我错过了什么?
P.S。这些屏幕截图来自 Visual Studio.
中的调试模式
为了使用 Intersect
,我建议实施 IEqualityComparer<T>
,像这样:
public class FD
{
public string Name { get; set; }
}
static void Main()
{
List<FD> fdList1 = new List<FD>();
fdList1.Add(new FD { Name = "a" });
List<FD> fdList2 = new List<FD>();
fdList2.Add(new FD { Name = "a" });
IEnumerable<FD> fd = fdList1.Intersect<FD>(fdList2, new ComparerFd()).ToList();
}
CamparerFd
应该是这样的:
public class ComparerFd : IEqualityComparer<FD>
{
public bool Equals(FD x, FD y)
{
return x.Name == y.Name;
}
public int GetHashCode(FD obj)
{
if(obj == null) return 0;
return obj.Name.GetHashCode();//Or whatever way to get hash code
}
}
如果您创建了自己的 class,并且没有覆盖 class 中的 Equals
方法,Intersect
方法将只比较引用对象,而不是属性。
采取以下内容,非常简单class:
class MyClass
{
int Value { get; set; }
public MyClass(int value)
{
this.Value = value;
}
}
现在,创建两个列表,都包含一个对象。对象的属性相同,但实例不同:
var list1 = new List<MyClass>
{
new MyClass(5)
};
var list2 = new List<MyClass>
{
new MyClass(5)
};
所以会发生以下情况:
list1[0].Equals(list2[0]); // false
list1.Intersect(list2); // No matches
如果您希望这些方法比较您的 MyClass
对象的属性,请实施 IEqualityComparer<MyClass>
,例如将 classes 签名更改为:
class MyClass : IEqualityComparer<MyClass>
{
..
}
或者,您可以覆盖 Equals
和 GetHashCode
,因为这些方法将被默认调用 IEqualityComparer
。
请参阅 this answer 以了解如何正确覆盖 Equals
和 GetHashCode
。
我有一个奇怪的问题。
我使用 Visual Studio 并且我正在用 C# 开发一个项目。
我有两个自定义 classes "Attr" 和 "FD" 并且我使用包含它们的对象的列表,例如
List<Attr> attrList = new List<Attr>();
List<FD> fdList = new List<FD>();
所以当我试图找到两个列表的交集时,结果不是我所期望的。为了使它更简单,我尝试 Intersect similar Objects 结果又是错误的。出了什么问题?
这是fd。它是 class FD 的对象。
这是 ff,它也是 FD class 的一个对象。
如您所见,这些对象包含完全相同的值。
方法 GetLeft() returns 包含 class Attr.
所以当我试图找到这两个列表之间的交集时 (fd.GetLeft() 和 ff.GetLeft() ) 结果什么都没有(它应该是一个包含 Attr 对象的列表 "A")。
我错过了什么?
P.S。这些屏幕截图来自 Visual Studio.
中的调试模式为了使用 Intersect
,我建议实施 IEqualityComparer<T>
,像这样:
public class FD
{
public string Name { get; set; }
}
static void Main()
{
List<FD> fdList1 = new List<FD>();
fdList1.Add(new FD { Name = "a" });
List<FD> fdList2 = new List<FD>();
fdList2.Add(new FD { Name = "a" });
IEnumerable<FD> fd = fdList1.Intersect<FD>(fdList2, new ComparerFd()).ToList();
}
CamparerFd
应该是这样的:
public class ComparerFd : IEqualityComparer<FD>
{
public bool Equals(FD x, FD y)
{
return x.Name == y.Name;
}
public int GetHashCode(FD obj)
{
if(obj == null) return 0;
return obj.Name.GetHashCode();//Or whatever way to get hash code
}
}
如果您创建了自己的 class,并且没有覆盖 class 中的 Equals
方法,Intersect
方法将只比较引用对象,而不是属性。
采取以下内容,非常简单class:
class MyClass
{
int Value { get; set; }
public MyClass(int value)
{
this.Value = value;
}
}
现在,创建两个列表,都包含一个对象。对象的属性相同,但实例不同:
var list1 = new List<MyClass>
{
new MyClass(5)
};
var list2 = new List<MyClass>
{
new MyClass(5)
};
所以会发生以下情况:
list1[0].Equals(list2[0]); // false
list1.Intersect(list2); // No matches
如果您希望这些方法比较您的 MyClass
对象的属性,请实施 IEqualityComparer<MyClass>
,例如将 classes 签名更改为:
class MyClass : IEqualityComparer<MyClass>
{
..
}
或者,您可以覆盖 Equals
和 GetHashCode
,因为这些方法将被默认调用 IEqualityComparer
。
请参阅 this answer 以了解如何正确覆盖 Equals
和 GetHashCode
。