標籤:style blog io color ar 使用 sp div on
程式可以建立同一個類的多個對象,對象也稱為執行個體。可以儲存在命名變數中,也可以儲存在數組、集合中。使用這些變數來調用對象方法以及公用屬性的代碼稱為用戶端代碼。在C#等物件導向的語言中,典型的程式往往使用多個對象。
由於類是參考型別,因此類對象的的變數引用該對象在託管堆上的地址。如果將同一類的第二個對象分配給第一個對象,則兩個對象都引用該地址的對象。
類的執行個體使用new關鍵字建立的:
public class Person{ public string Name { get; set; } public int Age { get; set; } public Person(string name, int age) { Name = name; Age = age; } //Other properties, methods, events...}class Program{ static void Main() { Person person1 = new Person("Leopold", 6); Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age); // Declare new person, assign person1 to it. Person person2 = person1; //Change the name of person2, and person1 also changes. person2.Name = "Molly"; person2.Age = 16; Console.WriteLine("person2 Name = {0} Age = {1}", person2.Name, person2.Age); Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age); // Keep the console open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); }}/* Output: person1 Name = Leopold Age = 6 person2 Name = Molly Age = 16 person1 Name = Molly Age = 16*/
由於結構是實值型別,因此結構對象的變數具有整個對象的副本。結構的執行個體也可以用new關鍵字來建立,但這不是必須的,如下:
public struct Person{ public string Name; public int Age; public Person(string name, int age) { Name = name; Age = age; }}public class Application{ static void Main() { // Create struct instance and initialize by using "new". // Memory is allocated on thread stack. Person p1 = new Person("Alex", 9); Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age); // Create new struct object. Note that struct can be initialized // without using "new". Person p2 = p1; // Assign values to p2 members. p2.Name = "Spencer"; p2.Age = 7; Console.WriteLine("p2 Name = {0} Age = {1}", p2.Name, p2.Age); // p1 values remain unchanged because p2 is copy. Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age); // Keep the console open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); }}/* Output: p1 Name = Alex Age = 9 p2 Name = Spencer Age = 7 p1 Name = Alex Age = 9*/
p1和p2的記憶體在縣城堆棧上進行分配。該記憶體隨聲明它的類型或方法一起回收,這就是在賦值時複製結構的一個原因,相比之下,當對類執行個體對象的所有引用都超出範圍時,為該類執行個體分配的記憶體將由通用語言執行平台自動回收(記憶體回收)。無法像在C++中那樣明確地銷毀類對象。
在比較兩個對象是否相等時,首先必須明確是想知道兩個變數是否表示記憶體中的同一對象,還是想知道這兩個對象的一個或多個欄位的值是否相等。如果要對值進行比較,則必須考慮這兩個對象是實值型別(結構)的執行個體,還是參考型別(類、委託、數組)的執行個體。
- 若要確定兩個類型執行個體是否引用記憶體中的同一位置(意味具有相同的表示),可以使用靜態(Equaals)方法。(System.Object是所有實值型別和參考型別的隱式基類,其中包含使用者定義的結構和類)
- 若要確定兩個結構執行個體中的執行個體欄位是否具有相同的值,可使用ValueType.Equals方法。(由於所有的結構都隱式繼承自System.ValueType,因此可以直接在對象上調用該方法,如下所示)
// Person is defined in the previous example.//public struct Person//{// public string Name;// public int Age;// public Person(string name, int age)// {// Name = name;// Age = age;// }//}Person p1 = new Person("Wallace", 75);Person p2;p2.Name = "Wallace";p2.Age = 75;if (p2.Equals(p1)) Console.WriteLine("p2 and p1 have the same values.");// Output: p2 and p1 have the same values.
Equals 的 System.ValueType 實現使用反射,因為它必須能夠確定任何結構中有哪些欄位。在建立自己的結構時,重寫Equals 方法可以提供針對類型的高效求等演算法。要確定兩個類執行個體中欄位的值是否相等,可以使用Equals方法或==運算子。但是,只有類通過已重寫或重載提供關於那種類型對象的相等含義的自訂時,才能使用它們。類也可以實現IEquatable<T>介面或IEqualityComparer<T>介面。這兩個介面都提供可用於測試值相等性的方法。
C#編程(7_對象)