Consider the below code -
// given class abc
class abc
{
public string firstName {get;set;}
public string lastName {get;set;}
}
class program
{
static void Main()
{
var a1 = new abc();
var a2 = new abc(); // object of same class
if (a1==a2) //always return false
{
// some code here
}
}
}
答案 0 :(得分:2)
当您使用==
时,您正在比较引用而不是对象内容
因为当你这样做时,引用不一样
var a1 = new abc();
var a2 = new abc();
a1
在内存中分配(称为实例),a2
在内存中有另一个分配(它将是另一个实例)
请看看如何切换GetHashcode
请
答案 1 :(得分:1)
它是同一个类但不是同一个类的实例。假设您要比较每个由班级代表的2名学生
学生
该类的两个实例很可能带有不同的值,例如姓名,年龄等。这些应该(出于显而易见的原因)不相等。
答案 2 :(得分:1)
你必须描述哪些类实例是相同的,例如当且仅当两个abc
个实例具有相等的firstName
和lastName
属性值时,才允许它们相等:
class abc {
public string firstName { get; set; }
public string lastName { get; set; }
public override bool Equals(object obj) {
abc other = obj as abc;
if (object.ReferenceEquals(null, other))
return false;
else
return string.Equals(firstName, other.firstName) &&
string.Equals(lastName, other.lastName);
}
public override int GetHashCode() {
return (lastName == null ? 0 : lastName.GetHashCode()) ^
(firstName == null ? 0 : firstName.GetHashCode());
}
}
....
var a1 = new abc();
var a2 = new abc(); // object of same class
if (a1 == a2) // now it'll return true
{
// some code here
}
// it'll be still false: a1 and a2 are different references
if (object.ReferenceEquals(a1, a2)) {
// some other code here
}
如果您不提供Equals
和GetHashCode
方法,。Net将使用参照等式(如果它们具有相同的引用,则实例相等):在您的情况下a1
和a2
是不同的引用,默认情况下为a1 != a2
。
有关详细信息,请参阅https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx
答案 3 :(得分:1)
默认情况下,operator ==通过确定两个引用是否指示同一对象来测试引用相等性。如果要更改此行为,则应覆盖operator ==。
答案 4 :(得分:1)
这样想:
var alicesBall = new GreenBall();
var bobsBall = new GreenBall();
你现在有两个球:爱丽丝的球和鲍勃的球。如果有人会问你们两个球是否是同一个球 - 不一样善良 - 你可能会说“不”。
但如果有人要问两个球是否都有相同类型的球 - 在这种情况下是一个绿球 - 你可能会回答“当然”。
您要比较的是a1和a2是否具有相同的类型。
答案 5 :(得分:0)
比较对象的属性更好。 这是我的建议:
if (a1.firstName==a2.firstName && a1.lastName == a2.lastName){
//some code here
}
答案 6 :(得分:0)
使用==运算符比较两个对象会比较内存中的地址,而不是对象本身。在为它们提供相同的值后尝试使用Object.Equals()方法或定义自己的.Equals()方法。
来自MSDN:
Equals的默认实现支持引用相等 引用类型和值类型的按位相等。参考 等于意味着被比较的对象引用引用 同一个对象。按位相等意味着被比较的对象具有 相同的二进制表示。
请注意,派生类型可能会覆盖要实现的Equals方法 价值平等。值相等意味着比较对象具有 相同的值,即使它们具有不同的二进制表示。对于 例如,考虑两个表示数字1.10的Decimal对象 和1.1000。 Decimal对象没有按位相等,因为 他们有不同的二元表示来解释 不同数量的尾随零。但是,对象具有价值 平等,因为数字1.10和1.1000被认为是相等的 比较目的,因为尾随零是无关紧要的。
这引自以下内容:link。
“现在,在幕后,CLR实际上实现了托管对象引用作为垃圾收集器拥有的对象的地址,但这是一个实现细节。没有理由除了效率和灵活性之外还必须这样做。 C#引用可以通过仅对垃圾收集器有意义的opaque句柄来实现,坦率地说,这是我更喜欢它们的方式。“句柄”恰好是运行时的地址实际上是一个实现细节,我应该既不知道也不依赖。(这是封装的全部要点;客户不必知道。)“
就程序员而言,它只是一个指针/地址。但对于编译器来说,这只是简单的地址。因此,虽然它们的使用方式不同(一种类型是安全的,另一种类型不是),但就编译器而言,它们都是指针,直到Microsoft决定以不同方式实现CLR。
答案 7 :(得分:0)
首先要知道的是,对象(类)是通过引用而非值创建的,当您使用==
比较器时,它将在处理"时检查引用相等性。 REF"数据类型,因为它是该数据类型的默认Equals
行为。 (希望有意义,如果不是我可以更具体)。
要解决您的问题,您应该覆盖Equals
方法来比较存储在对象内部的值,而不是检查引用相等性。
示例:
class abc
{
public string firstName {get;set;}
public string lastName {get;set;}
// custom equality comparer
public override bool Equals(object other)
{
if ( other is abc )
{
abc comparer = other as abc;
if ( comparer != null )
{
return string.Equals(comparer.firstName, this.firstName)
&&
string.Equals(comparer.lastName, this.lastName);
}
}
return base.Equals(other);
}
}
答案 8 :(得分:-1)
因为在两个不同的内存位置有两个不同的对象。
您可以使用GetType()和typeof()来比较类。