C# 比较两个对象列表
我的c#应用程序中有几个类 我有一个plant类,它的构造函数采用名称和权重 然后我有一个水果类,它继承了plant并添加了种子数属性 我还有一个从plant继承的Veg类,并添加了savoryLevel属性 用户可以将水果和蔬菜添加到它们的列表中 我在水果中重载了==运算符,以便它比较水果和蔬菜的名称,如果它们的名称相同,它会告诉您。我的问题是,当我试图比较整个列表以找到重复项时,我根本无法让代码正常工作 这是我的一些代码 植物类C# 比较两个对象列表,c#,list,inheritance,C#,List,Inheritance,我的c#应用程序中有几个类 我有一个plant类,它的构造函数采用名称和权重 然后我有一个水果类,它继承了plant并添加了种子数属性 我还有一个从plant继承的Veg类,并添加了savoryLevel属性 用户可以将水果和蔬菜添加到它们的列表中 我在水果中重载了==运算符,以便它比较水果和蔬菜的名称,如果它们的名称相同,它会告诉您。我的问题是,当我试图比较整个列表以找到重复项时,我根本无法让代码正常工作 这是我的一些代码 植物类 public string name; pub
public string name;
public string weight;
public Plant(string name, string weight)
{
this.name = name;
this.email = weight;
}
....
public static bool operator ==(Plant a, Plant b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
// Return true if the fields match:
return a.name == b.name;
}
然后是新的水果构造
string seeds;
public fruit(string name, string weight, string seeds)
: base(name, weight)
{
this.seeds
}
这是蔬菜
string savoryLevel;
public fruit(string name, string weight, string savouryLevel)
: base(name, weight)
{
this.savoryLevel
}
这里是我比较两个实例的主要地方,这很好
Fruit f = new Fruit("apple", "2", "5");
Veg v = new Veg("carrot", "3", "7");
if (f == v)
{
Console.WriteLine("They are the same");
}
else{
Console.WriteLine("They are different");
}
这是一个棘手的部分,我需要遍历我的整个蔬菜和水果列表,看看是否有任何水果与蔬菜同名
直接使用列表是行不通的
List<Fruit> fr = new List<Fruit>();
List<Veg> ve = new List<Veg>();
if(fr == ve){
Console.....
}
else{
Console....
}
List fr=新列表();
List ve=新列表();
如果(fr==ve){
安慰
}
否则{
安慰
}
那么,我如何让这些列表进行比较,并打印出一些结果,说明它们是相同的还是不同的呢?
非常感谢您的帮助,谢谢。
请询问您是否需要更多信息。如果您想比较相同索引下的项目
Zip
方法可能很有用:
bool result = fr.Zip(ve, (f,v) => new { f, v }).All(x => x.f == x.v);
Zip
方法创建对应项对,然后将每对项放入匿名类型。而All
方法只是检查成对中的所有项目是否相等。如果要比较相同索引中的项目Zip
方法可能很有用:
bool result = fr.Zip(ve, (f,v) => new { f, v }).All(x => x.f == x.v);
Zip
方法创建对应项对,然后将每对项放入匿名类型。而All
方法只是检查配对中的所有项目是否相等。如果您想对每个项目进行排序,可以这样做
foreach(var fruit in fr)
{
if(ve.Any(x => x.Name == fruit.Name))
{
Console.Write(fruit.Name + " is in both lists");
}
}
如果你想对每一件物品进行分类,你可以这样做
foreach(var fruit in fr)
{
if(ve.Any(x => x.Name == fruit.Name))
{
Console.Write(fruit.Name + " is in both lists");
}
}
我会使用LINQ,而不是(或者除了)重载
=
操作符,选择“更原生的”对象。Equals
和对象。GetHashCode
public override int GetHashCode()
{
return this.name.GetHashCode();
}
public override bool Equals(object b)
{
Plant bPlant = b as Plant;
// If one is null, but not both, return false.
if (bPlant == null)
{
return false;
}
// Return true if the fields match:
return this.name == b.name;
}
然后您可以使用LINQ:
return fr.SequenceEquals(ve);
当然,请注意,顾名思义,这仅在fr
和ve
完全相等时才有效。也就是说,它们之间的顺序必须是相同的:如果两者都包含“胡萝卜,花椰菜”,你就可以了,但如果一个是“胡萝卜,花椰菜”,另一个是“花椰菜,胡萝卜”,这将返回false
除非我误解了,事实上你想让交叉点不知道它们是相等的,在这种情况下:
return fr.Intersect(ve);
我会使用LINQ,而不是(或者除了)重载
=
操作符,选择“更原生的”对象。Equals
和对象。GetHashCode
public override int GetHashCode()
{
return this.name.GetHashCode();
}
public override bool Equals(object b)
{
Plant bPlant = b as Plant;
// If one is null, but not both, return false.
if (bPlant == null)
{
return false;
}
// Return true if the fields match:
return this.name == b.name;
}
然后您可以使用LINQ:
return fr.SequenceEquals(ve);
当然,请注意,顾名思义,这仅在fr
和ve
完全相等时才有效。也就是说,它们之间的顺序必须是相同的:如果两者都包含“胡萝卜,花椰菜”,你就可以了,但如果一个是“胡萝卜,花椰菜”,另一个是“花椰菜,胡萝卜”,这将返回false
除非我误解了,事实上你想让交叉点不知道它们是相等的,在这种情况下:
return fr.Intersect(ve);
您真的不需要重载
Equals
方法来确定是否有不同之处。如果您正在寻找不同的行为,而不是不同的结果,则应使用重载Equals
方法
既然本例比较了两个不同类中的两个字符串成员,为什么不使用LINQ
来比较相同数据类型的成员本身呢
using System;
using System.Collections.Generic;
using System.Linq;
public class Test
{
public static void Main()
{
List<Fruit> f = new List<Fruit>();
Fruit fTemp = new Fruit() { name = "Kiwi" };
f.Add(fTemp);
fTemp = new Fruit() { name = "Tomato" };
f.Add(fTemp);
List<Veg> v = new List<Veg>();
Veg vTemp = new Veg() { name = "Tomato" };
v.Add(vTemp);
List<Veg> vDuplicates = v.Where(vegToCompare=>f.Any(fruitToCompare=>fruitToCompare.name.Equals(vegToCompare.name))).ToList();
vDuplicates.ForEach(a=>Console.WriteLine(a.name));
Console.WriteLine("Number of Duplicates Found: " + vDuplicates.Count);
}
}
public class Fruit
{
public string name;
}
public class Veg
{
public string name;
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
公开课考试
{
公共静态void Main()
{
列表f=新列表();
水果fTemp=新水果(){name=“Kiwi”};
f、 添加(fTemp);
fTemp=新水果(){name=“西红柿”};
f、 添加(fTemp);
列表v=新列表();
Veg vTemp=new Veg(){name=“Tomato”};
v、 添加(vTemp);
列出vdupplicates=v.Where(vegToCompare=>f.Any(foulttocompare=>foulttocompare.name.Equals(vegToCompare.name)).ToList();
vDuplicates.ForEach(a=>Console.WriteLine(a.name));
Console.WriteLine(“找到的重复数:+vDuplicates.Count”);
}
}
公共级水果
{
公共字符串名称;
}
公营蔬菜
{
公共字符串名称;
}
您真的不需要重载Equals
方法来确定是否有不同之处。如果您正在寻找不同的行为,而不是不同的结果,则应使用重载Equals
方法
既然本例比较了两个不同类中的两个字符串成员,为什么不使用LINQ
来比较相同数据类型的成员本身呢
using System;
using System.Collections.Generic;
using System.Linq;
public class Test
{
public static void Main()
{
List<Fruit> f = new List<Fruit>();
Fruit fTemp = new Fruit() { name = "Kiwi" };
f.Add(fTemp);
fTemp = new Fruit() { name = "Tomato" };
f.Add(fTemp);
List<Veg> v = new List<Veg>();
Veg vTemp = new Veg() { name = "Tomato" };
v.Add(vTemp);
List<Veg> vDuplicates = v.Where(vegToCompare=>f.Any(fruitToCompare=>fruitToCompare.name.Equals(vegToCompare.name))).ToList();
vDuplicates.ForEach(a=>Console.WriteLine(a.name));
Console.WriteLine("Number of Duplicates Found: " + vDuplicates.Count);
}
}
public class Fruit
{
public string name;
}
public class Veg
{
public string name;
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
公开课考试
{
公共静态void Main()
{
列表f=新列表();
水果fTemp=新水果(){name=“Kiwi”};
f、 添加(fTemp);
fTemp=新水果(){name=“西红柿”};
f、 添加(fTemp);
列表v=新列表();
Veg vTemp=new Veg(){name=“Tomato”};
v、 添加(vTemp);
列出vdupplicates=v.Where(vegToCompare=>f.Any(foulttocompare=>foulttocompare.name.Equals(vegToCompare.name)).ToList();
vDuplicates.ForEach(a=>Console.WriteLine(a.name));
Console.WriteLine(“找到的重复数:+vDuplicates.Count”);
}
}
公共级水果
{
公共字符串名称;
}
公营蔬菜
{
公共字符串名称;
}
我认为您应该使用IEquatable
并使用SequenceEquals()将列表转换为List
演示:
然后相等比较结束(因为它是假的)。重点在于