C#中的四种判等方法
public static bool operator==(MyClass left, MyClass right);
public static bool ReferenceEquals(object left, object right);
public static bool Equals(object left, object,right);
public virtual bool Equals(object right);
1. == (相等操作符)
int a = 3;
int b = 3;
Console.WriteLine(a == b); //True
object objA = (object)a;
object objB = (object)b;
Console.WriteLine(objA == objB); //False
值类型的相等性:对于内置值类型,如果操作数的值相等,等于运算符 == 返回 true,否则返回 false 。
Test t1 = new Test("user");
Test t2 = new Test("user");
Console.WriteLine(t1 == t2); //False
string s1 = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
string s2 = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
Console.WriteLine(s1 == s2); //True
引用类型的相等性(string除外):默认情况下,如果两个引用类型引用同一个对象,则这两个操作符相等返回 true,否则返回 false。
string 是一种特殊的引用类型,在C#语言中,重载了Object对象的相等操作符,所以string的比较是比较值。
2. ReferenceEquals是Object中的一个静态方法
它的源码如下所示:
public static bool ReferenceEquals (Object objA, Object objB) {
return objA == objB;
}
这个函数的作用其实从名字中就可以看出,即判断两个引用类型的对象是否指向同一个地址,由于已经知道了等号操作符的作用,从objA == objB 就可以推断出该函数是对对象的应用进行比较。
需要注意,ReferenceEquals只能用于引用类型,对于值类型的操作都会返回false,如下示例,
int a = 1;
int b = 1;
bool result1 = Object.ReferenceEquals(a, b);//output: False
bool result2 = Object.ReferenceEquals(a, a);//output: False
3. 实例Equals函数
// Returns a boolean indicating if the passed in object obj is
// Equal to this. Equality is defined as object equality for reference
// types and bitwise equality for value types using a loader trick to
// replace Equals with EqualsValue for value types).
public virtual bool Equals(Object obj)
{
return RuntimeHelpers.Equals(this, obj);
}
对于值类型来说,实例Equals函数与 == 操作符是等价的,都是比较两个对象的值。
对于引用类型来说,如果指定的对象等于当前对象(意为指向同一个地址),则为 true,否则为 false。 继承了Object的类型默认使用Object中的Equals函数,为了满足不同的需求,我们也可以重写该方法。
class Point
{
protected int x, y;
public Point() : this(0, 0)
{ }
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if ((obj == null) || ! this.GetType().Equals(obj.GetType()))
{
return false;
}
else {
Point p = (Point) obj;
return (x == p.x) && (y == p.y);
}
}
public override int GetHashCode()
{
return (x << 2) ^ y;
}
public override string ToString()
{
return String.Format("Point({0}, {1})", x, y);
}
}
4. 静态Equals函数
直接上源码
public static bool Equals(Object objA, Object objB)
{
if (objA == objB) {
return true;
}
if (objA == null || objB == null) {
return false;
}
return objA.Equals(objB);
}
-
- 将两个参数转换为object类,如果是值类型,就将其装箱成Object,成为引用类型,然后通过 == 运算符对比栈中的 指向内存的地址。
int a = 3;
int b = 3;
object objA = (object)a;
object objB = (object)b;
Console.WriteLine(objA == objB); //False
-
- 进行非空验证
-
- 调用 objA 对象的 Equals 方法,需要注意!这里调用的并不是 Object 类的 Equals 方法 而是当前传递过来的对象类 类型的 Equals 方法!