C# 比较两个对象列表

C# 比较两个对象列表,c#,list,inheritance,C#,List,Inheritance,我的c#应用程序中有几个类 我有一个plant类,它的构造函数采用名称和权重 然后我有一个水果类,它继承了plant并添加了种子数属性 我还有一个从plant继承的Veg类,并添加了savoryLevel属性 用户可以将水果和蔬菜添加到它们的列表中 我在水果中重载了==运算符,以便它比较水果和蔬菜的名称,如果它们的名称相同,它会告诉您。我的问题是,当我试图比较整个列表以找到重复项时,我根本无法让代码正常工作 这是我的一些代码 植物类 public string name; pub

我的c#应用程序中有几个类

我有一个plant类,它的构造函数采用名称和权重

然后我有一个水果类,它继承了plant并添加了种子数属性

我还有一个从plant继承的Veg类,并添加了savoryLevel属性

用户可以将水果和蔬菜添加到它们的列表中

我在水果中重载了==运算符,以便它比较水果和蔬菜的名称,如果它们的名称相同,它会告诉您。我的问题是,当我试图比较整个列表以找到重复项时,我根本无法让代码正常工作

这是我的一些代码 植物类

    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

演示:

然后相等比较结束(因为它是假的)。重点在于