C# 列表。包含对象比较失败
我有一个类“Class1”,在.NET2.0中有一个字符串变量“sText”。我已经创建了该类“lstclas1”的对象列表。设置字符串变量后,它存储该类的许多对象 完整代码为: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)
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):
另一个解决方案是重写
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();
}