The three major characteristics of object-oriented: encapsulation, inheritance, and polymorphism. So where do classes inherit from? In object-oriented languages, there is the concept of base class or super class, that is, all classes inherit from this class. This super class is called Object. The Object class is described in .net like this:
Supports all classes in the .NET Framework class hierarchy and provides low-level services for derived classes. This is the ultimate base class for all classes in the .NET Framework; it is the root of the type hierarchy.
Since it is a super class, Object defines some key methods. As follows:
Equals method - used to compare whether two instances are equal.
public virtual bool Equals(Object obj), compares whether the current instance is equal to obj;
public static bool Equals(Object objA,Object objB), compares whether the specified two instances are equal.
Finalize method - Allows an Object to attempt to release resources and perform other cleanup operations before Garbage Collection reclaims the Object.
GetHashCode method - Gets the Hash value of an object.
GetType method - Get the Type of the current instance.
MemberwiseClone method - creates a shallow copy of the current instance, that is, if the current instance has a value, the newly created instance only obtains the value of the value type, and the reference type does not obtain the value. .
ReferenceEquals method - compares two instances to see if they are the same, and has the same usage as static bool Equals(Object objA,Object objB).
ToString method - This is commonly used and is used to return the string of the current instance.
Object is a super class, so all classes in C# have these methods.
The following focuses on the Equals and ToString methods.
1. Object comparison
There are value types and reference types in C#. A simple understanding is that value types save the value of objects, while reference types are references to instances, similar to pointers in C language. Therefore, when using object comparison, the value type compares whether the values of two objects are equal, and the reference type compares whether the specified reference refers to the same object. Of course, sometimes the instance values pointed to by the reference types are compared to see if they are the same.
The following is the code for object comparison:
using System; using System.Collections.Generic; using System.Text; namespace YYS.CSharpStudy.MainConsole.AboutObject { public class Int32Value : ICloneable { //字段,定义字段最好赋上初值 private int intValue = 0; /// <summary> /// 属性 /// </summary> public int IntValue { get { return this.intValue; } set { this.intValue = value; } } /// <summary> /// 定义一个无参构造器 /// </summary> public Int32Value() { } /// <summary> /// 带参数的构造器 /// </summary> public Int32Value(int value) { this.intValue = value; } ///// <summary> ///// 实现ICloneable接口 ///// </summary> public object Clone() { return this.MemberwiseClone(); } } }
Call:
using System; using YYS.CSharpStudy.MainConsole.AboutObject; namespace YYS.CSharpStudy.MainConsole { class Program { static void Main(string[] args) { //声明一个Int32Value类型的引用value1,指向一个实例 Int32Value value1 = new Int32Value(30); //声明value2,指向value1,此时两个引用是指向一个实例的 Int32Value value2 = value1; //使用==比较 Console.WriteLine(string.Format("value1和value2 {0}", value1 == value2 ? "相同" : "不相同"));//相同 //调用Clone,复制一个value1的副本,赋值给value2 //此时是两个实例了 value2 = (Int32Value)value1.Clone(); //使用==比较 Console.WriteLine(string.Format("value1和value2 {0}", value1 == value2 ? "相同" : "不相同"));//不相同 //将value1赋给value2,此时他们指向同一个实例 value2 = value1; //使用Equals比较 Console.WriteLine(string.Format("value1和value2 {0}", value1.Equals(value2) ? "相同" : "不相同"));//相同 //调用Clone,复制一个value1的副本,赋值给value2 //此时是两个实例了 value2 = (Int32Value)value1.Clone(); //使用Equals比较 Console.WriteLine(string.Format("value1和value2 {0}", value1.Equals(value2) ? "相同" : "不相同"));//不相同 Console.ReadLine(); } } }
Result:
As can be seen from the code:
a. For reference types, the = operator passes the reference from one variable to another, so the variables on both sides of = refer to the same object;
b. For two variables that reference the same, use = = operator returns true;
c. The Clone method of an object generates a new instance and returns a reference to the instance. All field values of the instance are the same as the original object, that is, the Clone method obtains a copy of the object. The protection method MemberwiseClone inherited from the Object class returns a copy of the current object;
d. For the object returned by the Clone method, its reference is different from the original object, and the == operator returns false;
e. The result of the Equals method inherited from Object is the same as the == operator. It just compares whether the current reference (this) and the reference saved by the parameter refer to the same object.
Based on the above code, rewrite the Equals method.
using System; using System.Collections.Generic; using System.Text; namespace YYS.CSharpStudy.MainConsole.AboutObject { public class Int32Value : ICloneable { //字段,定义字段最好赋上初值 private int intValue = 0; /// <summary> /// 属性 /// </summary> public int IntValue { get { return this.intValue; } set { this.intValue = value; } } /// <summary> /// 定义一个无参构造器 /// </summary> public Int32Value() { } /// <summary> /// 带参数的构造器 /// </summary> public Int32Value(int value) { this.intValue = value; } ///// <summary> ///// 实现ICloneable接口 ///// </summary> public object Clone() { return this.MemberwiseClone(); } /// <summary> /// 覆盖Equals方法 /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { bool isEquals = Object.ReferenceEquals(obj, this); if (isEquals == false) { Int32Value value = obj as Int32Value; if (value != null) { isEquals = value.intValue == this.intValue; } } return isEquals; } } }
Call
using System; using YYS.CSharpStudy.MainConsole.AboutObject; namespace YYS.CSharpStudy.MainConsole { class Program { static void Main(string[] args) { //声明一个Int32Value类型的引用value1,指向一个实例 Int32Value value1 = new Int32Value(30); //声明value2,指向value1,此时两个引用是指向一个实例的 Int32Value value2 = value1; //使用==比较 Console.WriteLine(string.Format("value1和value2 {0}", value1 == value2 ? "相同" : "不相同"));//相同 //调用Clone,复制一个value1的副本,赋值给value2 //此时是两个实例了 value2 = (Int32Value)value1.Clone(); //使用==比较 Console.WriteLine(string.Format("value1和value2 {0}", value1 == value2 ? "相同" : "不相同"));//不相同 //将value1赋给value2,此时他们指向同一个实例 value2 = value1; //使用Equals比较 Console.WriteLine(string.Format("value1和value2 {0}", value1.Equals(value2) ? "相同" : "不相同"));//相同 //调用Clone,复制一个value1的副本,赋值给value2 //此时是两个实例了 value2 = (Int32Value)value1.Clone(); //使用Equals比较 Console.WriteLine(string.Format("value1和value2 {0}", value1.Equals(value2) ? "相同" : "不相同"));//相同 Console.ReadLine(); } } }
Result:
Modified code:
Covers the Equals method, and the program running result is different: Equals is no longer compared Check whether the object references saved by the two variables are the same, but compare whether the objects referenced by the two variables have the same attribute values.
The execution process of Equals after overwriting is as follows:
Let’s take a look at the specific execution process of the Equals method after overwriting:
a. Use the Object static method ReferenceEquals to compare the parameter obj and the current object reference (this ) are the same, if the reference is the same, it must be the same object;
b. If the variable obj is not the same as the current reference, use the as operator to try to convert the obj type to the same type as the current object. Successful conversion means obj The variable refers to the same object as the current object class. The as operator converts the reference of the object, otherwise it returns null. Only objects of the same type need to be compared. Objects of different types must be different objects;
c. If as If the operator successfully converts the object, it will further compare whether the current object reference (this) and the field value of the object referenced by the parameter obj are equal.
It can be seen from the above two pieces of code:
== and the Equals method of the Object class both compare whether the references of the objects are the same, and do not compare whether the fields of the objects are equal; and the Equals method can be overridden, In order to allow it to perform equivalence comparison or other comparisons on the fields of the object.
Therefore, if you need to compare two C# reference type variables, you can use the == operator unless you are sure that what needs to be compared is an object reference. Otherwise, you should use the Equals method of the object to prevent the class to which the object belongs from overriding this method.
上面是引用类型的比较,相对来说,值类型的比较就比较纯粹。值类型是不存在引用的,所以值类型就是比较两个对象值是否相等。当然如果覆盖了Equals方法就除外了。不过一般情况下,我们无需覆盖Equals方法。对于引用类型来说,等值比较就是比较对象的引用,引用不同的两个对象应该就是不同的对象;对于值类型来说,比较的就是所有字段的值,字段值不同的两个对象是不同的对象。只有在特殊情况下,才需要覆盖Equals方法,已定义某个类特殊的对象比较方法。
对于覆盖Equals方法,要注意:
注意:理论上可以用任意代码覆盖Equals方法,但要保证如下原则:
a、Equals只能用于对象比较,不能做其它任何用途;
b、对于两个已存在的对象,在对象未作任何改变的情况下,无论任何时候调用Equals方法,返回的结果应该是一样的;
c、对于对象a和b,则a.Equalse(b)和b.Equals(a)返回的结果应该是一样的;
d、覆盖了Equals方法,同时要覆盖GetHashCode(方法),这个后面再详细说明。
二、ToString()
代码:
public class Int32Value : ICloneable { //字段,定义字段最好赋上初值 private int intValue = 0; /// <summary> /// 属性 /// </summary> public int IntValue { get { return this.intValue; } set { this.intValue = value; } } /// <summary> /// 定义一个无参构造器 /// </summary> public Int32Value() { } /// <summary> /// 带参数的构造器 /// </summary> public Int32Value(int value) { this.intValue = value; } ///// <summary> ///// 实现ICloneable接口 ///// </summary> public object Clone() { return this.MemberwiseClone(); } /// <summary> /// 重写ToString方法 /// </summary> /// <returns></returns> public override string ToString() { return this.intValue.ToString(); //return "重写ToString"; } }
调用:
class Program { static void Main(string[] args) { Int32Value value = new Int32Value(30); Console.WriteLine(value.ToString());//30 //Console.WriteLine(value.ToString());//重写ToString Console.ReadLine(); } }
可以看出,ToString方法可以用任意代码覆盖,只要返回string即可,但是在覆盖时也要返回符合需求的返回值。
以上就是C#基础知识整理:基础知识(12) 超类Object 的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!