支撑 .NET Framework 类条理组织中的一切类,并为派生类供应低级别效劳。这是 .NET Framework 中一切类的终究基类;它是范例条理组织的根。
既然是超类,Object定义了一些症结的要领。以下:
Equals要领——用于比较两个实例是不是相称。
public virtual bool Equals(Object obj),比较当前实例是不是与obj相称;
public static bool Equals(Object objA,Object objB),比较指定两个实例是不是相称。
Finalize 要领——许可 Object 在“垃圾接纳”接纳 Object 之前尝试开释资本并实行其他清算操纵。
GetHashCode 要领——猎取一个对象的Hash值。
GetType要领——猎取当前实例的Type。
MemberwiseClone 要领——建立当前实例的浅表副本,也就是假如当前实例有值,新建立的实例中只猎取值范例的值,援用范例是没有猎取值。
ReferenceEquals 要领——比较两个实例是不是雷同,与static bool Equals(Object objA,Object objB)用法一样。
ToString 要领——这个日常平凡用的比较多,用于返回当前实例的string。
Object是超类,所以C#中的一切类都具有这些要领。
下面偏重引见下Equals和ToString要领。
一、对象比较
C#中有值范例和援用范例,简朴的明白就是值范例保留对象的值,而援用范例是实例的援用,类似于C言语的指针。因而在运用对象的比较的时刻,值范例比较两个对象值是不是相称,援用范例比较指定的援用是不是援用同一个对象。固然偶然也会比较援用范例指向的实例值是不是雷同。
下面是对象比较的代码:
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(); } } }
挪用:
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(); } } }
由代码能够看出:
a、关于援用范例,=运算符将援用从一个变量通报到另一个变量,所以=双方的变量援用同一个对象;
b、关于援用雷同的两个变量,运用==运算符返回true;
c、对象的Clone要领发生一个新实例,返回该实例的援用,该实例的一切字段值和原对象雷同,即Clone要领获得对象的一个副本。从Object类继续下来的庇护要领MemberwiseClone返回当前对象的副本;
d、关于Clone要领返回的对象,其援用和原对象差别,==运算符返回false;
e、从Object继续下来的Equals要领效果和==运算符雷同,只是比较当前援用(this)和参数保留的援用是不是援用到了同一个对象上。
在上述代码的基础上,重写Equals要领。
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; } } }
挪用
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(); } } }
效果:
修改后的代码:
掩盖了Equals要领,顺序运转效果则差别了:Equals不再比较两个变量保留的对象援用是不是雷同,而是比较两个变量所援用的对象是不是具有雷同的属性值。
掩盖后的Equals实行流程是如许的:
我们看一下掩盖后Equals要领的细致实行流程:
a、运用Object静态要领ReferenceEquals比较参数obj和当前对象援用(this)是不是雷同,假如援用雷同,则必为雷同对象;
b、假如变量obj和当前援用不雷同,则运用as运算符,尝试将obj范例转换和当前对象雷同的范例,转换胜利示意obj变量援用着和当前对象类雷同的对象,as运算符转换后对象的援用,不然返回null,只需同范例的对象才须要比较,差别范例的对象必定是差别的对象;
c、假如as运算符转换对象胜利,则进一步比较当前对象援用(this)和参数obj援用对象的字段值是不是相称。
由上面两段代码能够看出:
==和Object类的Equals要领都是比较对象的援用是不是雷同,并不比较对象的字段是不是相称;而Equals要领能够掩盖,以求让其对对象的字段举行等值比较或许别的的比较的需求。
因而,假如须要比较两个C#援用范例变量,除非肯定须要比较的就是对象援用时才能够运用==运算符,不然应当运用对象的Equals要领,防备对象所属的类掩盖了这个要领。
上面是援用范例的比较,相对来讲,值范例的比较就比较地道。值范例是不存在援用的,所以值范例就是比较两个对象值是不是相称。固然假如掩盖了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 的内容,更多相关内容请关注ki4网(www.ki4.cn)!