zoukankan      html  css  js  c++  java
  • C#中的结构与类

    总结起来,两者共有如下区别:

    转载自:http://www.agiledon.com/post/2009/03/Structure-vs-Class.html

    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。

  • 相关阅读:
    P1064 金明的预算方案
    P1062 数列
    P2258 子矩阵
    P1095 守望者的逃离
    P1201 [USACO1.1]贪婪的送礼者Greedy Gift Givers
    P1203 [USACO1.1]坏掉的项链Broken Necklace
    P1478 陶陶摘苹果(升级版)
    P2485 [SDOI2011]计算器
    逆元模板
    CloudStack 物理网络架构
  • 原文地址:https://www.cnblogs.com/dupeng0811/p/1422229.html
Copyright © 2011-2022 走看看