程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#中的結構與類的總結

C#中的結構與類的總結

編輯:關於C#

總結起來,兩者共有如下區別:

1、結構是值類型,類則是引用類型。因此前者是放在棧(Stack)裡,後者則僅僅是將引用地址存放在棧裡,而具體的值則存放在堆(heap)裡。如下圖所示:

2、據第1點可以得出結論,那就是類對象通常用來傳遞大數據,而結構對象則用來傳遞小數據。

3、類可以被繼承,而結構則不支持。

4、結構對象不能像類對象一樣賦值為null。

5、結構不能像類一樣定義析構器。

6、結構不能像類一樣定義為抽象的。

7、在結構中不能重寫方法,除非是object類型的如下方法:

Equals()

GetHashCode()

GetType()

ToString()

若要讓結構具有多態特性,可以讓其實現接口。

8、在類中定義的事件是線程安全的,而結構則不是。

9、結構總是具有一個默認的公共無參構造函數,但卻不能像類一樣定義私有的無參構造函數(結構也不能再定義公共的無參構造函數,這與類不相同):

    struct Me
    {
        private Me() // compile-time error
        {
        }
    }

    class Me
    {
        private Me() // runs Ok{
    }

10、類中的靜態構造函數會被調用,而結構卻不能。因此在結構中定義的靜態構造函數,雖然可以編譯通過,但卻沒有價值:

    struct myStructure
    {
        static myStructure()
        {
            Console.WriteLine("This is me a structure");
         }
    }
    class myClass
        static myClass()
        {
            Console.WriteLine("This is me a class");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
           myStructure s = new myStructure();//Nothing happen
           myClass c = new myClass();//Will out put This is me a class
           Console.Read();
        }
    }

11、結構不能像類一樣定義volatile字段。volatile字段主要用於並發,它相當於方法體的lock。

12、可以對結構類型使用sizeof,對類則不行。

13、類的字段會被自動初始化為0/false/null,而結構則不能。

14、在結構中不能直接對字段初始化,而類則可以。

    struct myStructure
    {
        public string x = 2;//Not allowed
    }
    class myClass
    {
        public string x = 2; //Allowed
    }

15、結構和類對於System.Object.Equals()方法的體現是不相同的。例如定義這樣的結構和類:

    struct StructurePerson
    {
         public string FirstName;
        public string LastName;
    }
    class ClassPerson
    {
        public string FirstName;
        public string LastName;
    }

如果運行如下的代碼:

    class Program
    {
        static void Main(string[] args)
        {
             StructurePerson strX = new StructurePerson();
            strX.LastName = "Bejaoui";
            strX.FirstName = "Bechir";
            StructurePerson strY = new StructurePerson();
            strY.LastName = "Bejaoui";
            strY.FirstName = "Bechir";

            if (strX.Equals(strY))
            {
                Console.WriteLine("strX = strY");
            }
            else
            {
                Console.WriteLine("strX != strY");
            }//This code displays strX = strY

            ClassPerson clsX = new ClassPerson();
            clsX.LastName = "Bejaoui";
            clsX.FirstName = "Bechir";
            ClassPerson clsY = new ClassPerson();
            clsY.LastName = "Bejaoui";
            clsY.FirstName = "Bechir";

            if (clsX.Equals(clsY))
            {
                Console.WriteLine("clsX = clsY");
            }
            else
            {
                Console.WriteLine("clsX != clsY");
            }//This code displays clsX != clsY
            Console.Read();
        }
    }

由於結構類型是值類型,因而Equals()方法比較的是兩個對象的值是否相等,如果相等則返回true;而類類型為引用類型,Equals()方法比較的是二者的引用地址(即指針)是否相等。很顯然,clsX和clsY是兩個不同的對象,它們在棧的地址是不相等的。如果修改代碼如下:

ClassPerson clsX = new ClassPerson();
clsX.LastName = "Bejaoui";
clsX.FirstName = "Bechir";
ClassPerson clsY = clsX;
if (clsX.Equals(clsY))
{
  Console.WriteLine("clsX = clsY");
}
else
{
  Console.WriteLine("clsX != clsY");

}//This code displays clsX = clsY

由於是直接將clsX賦值給clsY,因此兩個對象的引用地址相等,Equals()方法返回true。

其實對於值類型和引用類型的相等性比較,是一個比較復雜的問題。例如我們可以通過重寫Equals()方法增強或修改比較邏輯。重寫Equals()方法還必須重寫GetHashCode()方法。對於引用類型,還可以使用靜態方法ReferenceEquals()方法。此外,還可以重載操作符==。另外,對於String對象,則比較特殊,因為它使用了Immutable模式。雖然String類型是引用類型,但如果直接定義的兩個String對象的值相同,由於采用了Immutable模式的原因,這兩個對象其實是同一個對象,引用地址是相同的。因此不僅動態方法Equals()返回的是true,且靜態方法ReferenceEquals()返回的也是true。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved