Heim  >  Artikel  >  Backend-Entwicklung  >  C#-Grundwissenskompilierung: Grundwissen (12) Superklasse-Objekt

C#-Grundwissenskompilierung: Grundwissen (12) Superklasse-Objekt

黄舟
黄舟Original
2017-02-11 13:28:211174Durchsuche

Drei Hauptmerkmale der Objektorientierung: Kapselung, Vererbung und Polymorphismus. Woher erben Klassen? In objektorientierten Sprachen gibt es das Konzept der Basisklasse oder Superklasse, das heißt, alle Klassen erben von dieser Klasse. Diese Superklasse heißt Object. Die Object-Klasse wird in .net wie folgt beschrieben:
Unterstützt alle Klassen in der .NET Framework-Klassenhierarchie und stellt Low-Level-Dienste für abgeleitete Klassen bereit. Dies ist die ultimative Basisklasse für alle Klassen im .NET Framework; sie ist die Wurzel der Typhierarchie.
Da es sich um eine Superklasse handelt, definiert Object einige Schlüsselmethoden. Wie folgt:

Equals-Methode – wird verwendet, um zu vergleichen, ob zwei Instanzen gleich sind.
public virtual bool Equals(Object obj), vergleicht, ob die aktuelle Instanz gleich obj ist;
public static bool Equals(Object objA, Object objB), vergleicht, ob die beiden angegebenen Instanzen gleich sind.

Finalize-Methode – Ermöglicht einem Objekt, zu versuchen, Ressourcen freizugeben und andere Bereinigungsvorgänge durchzuführen, bevor die Garbage Collection das Objekt zurückfordert.

GetHashCode-Methode – Ruft den Hash-Wert eines Objekts ab.

GetType-Methode – Ruft den Typ der aktuellen Instanz ab.

MemberwiseClone-Methode – erstellt eine flache Kopie der aktuellen Instanz, d. h. wenn die aktuelle Instanz einen Wert hat, wird nur der Wert des Werttyps in der neu erstellten Instanz abgerufen, und der Referenztyp erhält nicht den Wert.

ReferenceEquals-Methode – vergleicht zwei Instanzen, um zu sehen, ob sie gleich sind, dasselbe wie der statische bool Equals(Object objA, Object objB).

ToString-Methode – Diese wird häufig verwendet, um die Zeichenfolge der aktuellen Instanz zurückzugeben.
Object ist eine Superklasse, daher verfügen alle Klassen in C# über diese Methoden.

Im Folgenden liegt der Schwerpunkt auf den Methoden Equals und ToString.
1. Objektvergleich
In C# gibt es Werttypen und Referenztypen. Ein einfaches Verständnis besteht darin, dass Werttypen den Wert von Objekten speichern, während Referenztypen Verweise auf Instanzen sind, ähnlich wie Zeiger in der C-Sprache. Daher vergleicht der Werttyp bei Verwendung des Objektvergleichs, ob die Werte zweier Objekte gleich sind, und der Referenztyp vergleicht, ob die angegebene Referenz auf dasselbe Objekt verweist. Natürlich werden manchmal die Instanzwerte, auf die die Referenztypen verweisen, verglichen, um festzustellen, ob sie gleich sind.
Das Folgende ist der Code für den Objektvergleich:

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();
        }
    }
}

Aufruf:

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();
        }
    }
}

Ergebnis:

Wie zu sehen ist aus dem Code:

a. Bei Referenztypen übergibt der =-Operator die Referenz von einer Variablen an eine andere, sodass die Variablen auf beiden Seiten von = auf dasselbe Objekt verweisen; Verwenden Sie für zwei Referenzen mit derselben Referenzvariable den Operator ==, um true zurückzugeben. Die Clone-Methode des Objekts generiert eine neue Instanz und gibt eine Referenz auf die Instanz zurück Die Instanz ist mit dem Originalobjekt identisch, das heißt, die Clone-Methode erhält eine Kopie des Objekts. Die von der Object-Klasse geerbte Schutzmethode MemberwiseClone gibt eine Kopie des aktuellen Objekts zurück.

d Für das von der Clone-Methode zurückgegebene Objekt unterscheidet sich seine Referenz vom Originalobjekt und der Operator == gibt false zurück ;

e. Das Ergebnis der von Object geerbten Equals-Methode ist das gleiche wie der ==-Operator. Es wird lediglich verglichen, ob die aktuelle Referenz (this) und die durch den Parameter gespeicherte Referenz auf dasselbe Objekt verweisen.

Schreiben Sie basierend auf dem obigen Code die Equals-Methode neu.

Aufruf

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;
        }
    }
}
Ergebnis:

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();
        }
    }
}
Geänderter Code:

deckt die Equals-Methode ab, und das Ergebnis der Programmausführung ist anders: Equals Vergleicht nicht mehr, ob die von zwei Variablen gespeicherten Objektreferenzen gleich sind, sondern vergleicht, ob die von den beiden Variablen referenzierten Objekte dieselben Eigenschaftswerte haben.
Der Ausführungsprozess von Equals nach dem Überschreiben ist wie folgt: Schauen wir uns den spezifischen Ausführungsprozess der Equals-Methode nach dem Überschreiben an:

a Verwenden Sie die statische Object-Methode ReferenceEquals, um die zu vergleichen Parameter obj und die aktuelle Objektreferenz (this) sind identisch. Wenn die Referenz identisch ist, muss es sich um dasselbe Objekt handeln.
b. Wenn die Variable obj und die aktuelle Referenz nicht identisch sind, verwenden Sie den Operator as Um zu versuchen, den obj-Typ in denselben Typ wie das aktuelle Objekt zu konvertieren, bedeutet dies, dass die obj-Variable auf dasselbe Objekt wie die aktuelle Objektklasse verweist, andernfalls wird nur null zurückgegeben Objekte desselben Typs müssen unterschiedliche Objekte sein Die Objekte, auf die der Parameter obj verweist, sind gleich.
Aus den beiden obigen Codeteilen ist ersichtlich:

== und die Equals-Methode der Object-Klasse vergleichen beide, ob die Referenzen der Objekte gleich sind, vergleichen jedoch nicht, ob die Felder gleich sind der Objekte gleich sind; und die Equals-Methode kann überschrieben werden, um einen Äquivalenzvergleich oder andere Vergleiche für die Felder des Objekts durchzuführen.
Wenn Sie also zwei C#-Referenztypvariablen vergleichen müssen, können Sie nur den ==-Operator verwenden, es sei denn, Sie sind sicher, dass es sich bei dem zu vergleichenden Objekt um eine Objektreferenz handelt. Andernfalls sollten Sie die Equals-Methode des Objekts verwenden um zu verhindern, dass die Klasse, zu der das Objekt gehört, diese Methode überschreibt.

    上面是引用类型的比较,相对来说,值类型的比较就比较纯粹。值类型是不存在引用的,所以值类型就是比较两个对象值是否相等。当然如果覆盖了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中文网(www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn