Q1: 一个值类型调用System.Object类定义的方法会不会发生装箱?
A1: 如果值类型重写了System.Object定义的虚方法(Equals, GetHashCode, ToString),调用时不会发生装箱,如果重写的方法中调用了基类的实现,则需要进行装箱;如果值类型调用了非虚方法(GetType, MemberwiseClone),则会发生装箱。
Q2: 为什么重写Equals方法需要同时重写GetHashCode方法?
A2: GetHashCode方法可以获取任意对象的Int32哈希码,System.Collections.HashTable类型,System.Generic.Dictionary类型以及其他一些集合的实现中,要求两个对象为了相等,必须拥有相同的哈希码。
Q3: System.Object类定义的Equals方法是用来判断对象的相等性还是同一性?
A3: System.Object类定义的Equals方法如下:
1 public virtual Boolean Equals(Object obj) 2 { 3 if (this == obj) 4 return true; 5 return false; 6 }它其实判断的是对象的同一性而不是相等性,通过如下代码可验证:
1 namespace Test 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 Person p1 = new Person() { Name = "Allen", Sex = true, Age = 25 }; 8 Person p2 = new Person() { Name = "Allen", Sex = true, Age = 25 }; 9 10 Console.WriteLine(p1.Equals(p2)); 11 } 12 } 13 14 class Person 15 { 16 public string Name { get; set; } 17 public bool Sex { get; set; } 18 public int Age { get; set; } 19 } 20 }返回结果为false.
Q4: 如何重写Equals方法使它用来判断相等性而不是同一性?
A4: 可在上例中Person类中重写Equals方法:
1 public override bool Equals(object obj) 2 { 3 if (obj == null) 4 return false; 5 6 if (obj.GetType() != this.GetType()) 7 return false; 8 9 Person p = (Person)obj; 10 return this.Name == p.Name && this.Sex == p.Sex && this.Age == p.Age; 11 }此时再运行上例中代码则会得到true.
PS: 除了重写Equals(object)外,还建议为自己的类型写Equals(Person)以增强性能:
1 public bool Equals(Person p) 2 { 3 if (p == null) 4 return false; 5 return Name == p.Name && Sex == p.Sex && Age == p.Age; 6 }
Q5: 重写了Equals方法后,如何判断两个对象的同一性?
A5: System.Object类提供了一个叫做ReferenceEquals的静态方法,可以用来比较同一性。
Q6: System.ValueType已经重写了System.Object的Equals方法,在自定义值类型的时候,还需要重写Equals方法吗?
A6: 最好重写,ValueType的Equals方法使用了反射技术,而CLR的反射机制很慢,重写Equals方法可提高性能。
Q7: 重写Equals方法应注意什么?
A7: 1)Equals必须是自反的,x.Equals(x)肯定为true; 2)Equals必须是对称的,x.Equals(y)返回的值一定等于y.Equals(x); 3)Equals必须是可传递的,x.Equals(y)返回true, y.Equals(z)返回true, 则x.Equals(z)也一定返回true; 4)Equals必须是一致的,比较的两个值没有变,Equals返回的值也不能变。
Q8: dynamic和var的区别是什么?
A8: dynamic是在运行时检测实际类型,var是在编译时编译器已经能够确定实际类型。例如定义了一个var str = "abc"; 这完全等同于定义了string str = "abc"; 编译器可以判断出str只能是string类型,用str调用string类型的方法和属性时,智能提示可以显示所有string类型的方法和属性,但当定义dynamic str = "abc"; 时,编译器并不知道str的实际类型,只会在运行时做判断,即使我们用str调用一个根本不存在的方法,同样可以通过变异,但运行时会报错。
转载于:https://www.cnblogs.com/Allen-Li/archive/2013/04/04/2998455.html
相关资源:垃圾分类数据集及代码