Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 列表。包含对象比较失败_C#_.net_List_Class_Object - Fatal编程技术网

C# 列表。包含对象比较失败

C# 列表。包含对象比较失败,c#,.net,list,class,object,C#,.net,List,Class,Object,我有一个类“Class1”,在.NET2.0中有一个字符串变量“sText”。我已经创建了该类“lstclas1”的对象列表。设置字符串变量后,它存储该类的许多对象 完整代码为: public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e)

我有一个类“Class1”,在.NET2.0中有一个字符串变量“sText”。我已经创建了该类“lstclas1”的对象列表。设置字符串变量后,它存储该类的许多对象

完整代码为:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (!lstClass1.Contains(new Class1("text1")))
            lstClass1.Add(new Class1("text1"));
    }

    public List<Class1> lstClass1 = new List<Class1>();
}

public class Class1
{
    public Class1(string sText)
    {
        this.sText = sText;
    }

    public string sText = "";
}
但它始终允许添加文本“text1”,即使列表中已有一个包含“text1”字符串的对象。我的假设是,在第一次按钮单击事件“button1_click”时,对象将被添加,因为列表为空,但在下一次按钮单击列表。包含函数将检查列表中是否已经存在字符串变量“text1”的对象,如果找到,则不会添加该对象。但它始终允许添加文本为“text1”的对象,即使该对象已存在于列表中

请注意:我没有使用简单的字符串列表或字符串列表,因为我想用一种简单的方式解释我的列表、类和对象的大问题。

使用方法:

此代码:

if (!lstClass1.Contains(new Class1("text1")))
    lstClass1.Add(new Class1("text1"));
只有为
Class1
提供
Equals()
GetHashCode()
方法,以便能够在此类的两个对象之间进行比较时,才能工作。为了实现这一点,您的类应该实现
IEquatable
接口。 所以你的班级可以是这样的:

public class Class1 : IEquatable<Class1>
{
    public Class1(string sText)
    {
        this.sText = sText;
    }

    public string sText = "";

    public bool Equals(Class1 other) 
    {
      if (other == null) 
         return false;

      if (this.sText == other.sText)
         return true;
      else
         return false;
    }

    public override int GetHashCode()
    {
      return this.sText.GetHashCode();
    }
}
公共类类别1:IEquatable
{
公共类别1(字符串文本)
{
this.sText=sText;
}
公共字符串sText=“”;
公共布尔等于(1类其他)
{
如果(其他==null)
返回false;
if(this.sText==other.sText)
返回true;
其他的
返回false;
}
公共覆盖int GetHashCode()
{
返回此.sText.GetHashCode();
}
}

这会失败,因为列表在您的实例上调用了
Equals
,而默认实现会检查引用的相等性。尽管对象具有name属性值,但它是一个不同的实例,因此引用将不相等

Class1
中,重写
Equals
方法以比较基础属性

public override bool Equals(object other)
{
  Class1 rhs=other as Class1;
  if(rhs==null) return false;

  return this.sText == rhs.sText;
}

这里面临的问题是对象和实例之间的问题。当您检查以下内容时,您基本上是在问“是否在收藏中?”

显然不可能,因为你刚刚创造了它。您需要检查的是该对象的内容。最简单的方法是遍历集合并检查每个对象的内容

使用LINQ很容易做到这一点(尽管我不确定它是否适用于.NET 2.0):


另一个解决方案是重写GethasoCudie()/<代码>和<>代码>等于类的方法,如果两个对象的内容相同,则将两个对象视为“相等”。这样就可以进行彻底的比较。

只有在您的案例中实现IEquatable时,Contains才会正确工作

您可以改用以下代码:

public class Class1 //: IEquatable<Class1>
{
    public string sText = "";
    public Class1(string sText)
    {
        this.sText = sText;
    }

    //public bool Equals(Class1 other)
    //{
    //    return this.sText == other.sText;
    //}
}
static void Main(string[] args)
{
    List<Class1> lstClass1 = new List<Class1>() { new Class1("text1") };
    if (!lstClass1.Contains(new Class1("text1")))
        lstClass1.Add(new Class1("text1"));
    Console.WriteLine(lstClass1.Count);
    Console.ReadKey();
}
public类Class1//:i可满足
{
公共字符串sText=“”;
公共类别1(字符串文本)
{
this.sText=sText;
}
//公共布尔等于(1类其他)
//{
//返回this.sText==other.sText;
//}
}
静态void Main(字符串[]参数)
{
List lstclas1=newlist(){new Class1(“text1”)};
如果(!lstclas1.Contains(new Class1(“text1”))
添加(新类别1(“文本1”);
控制台写入线(lstclas1.Count);
Console.ReadKey();
}

取消注释注释注释行,您将看到差异。

您提供了Class1的默认Equals和GetHashCode方法的实现吗?不确定为什么不将该
新Class1(“text1”)
存储到新的
Class1
类型的变量中,顺便说一句。不需要构造两次。只需构造一次,在变量上检查它,然后从变量中存储它。
public override bool Equals(object other)
{
  Class1 rhs=other as Class1;
  if(rhs==null) return false;

  return this.sText == rhs.sText;
}
!lstClass1.Contains(new Class1("text1"))
!lstClass1.Any(i => i.Text == "text1")
public class Class1 //: IEquatable<Class1>
{
    public string sText = "";
    public Class1(string sText)
    {
        this.sText = sText;
    }

    //public bool Equals(Class1 other)
    //{
    //    return this.sText == other.sText;
    //}
}
static void Main(string[] args)
{
    List<Class1> lstClass1 = new List<Class1>() { new Class1("text1") };
    if (!lstClass1.Contains(new Class1("text1")))
        lstClass1.Add(new Class1("text1"));
    Console.WriteLine(lstClass1.Count);
    Console.ReadKey();
}