zoukankan      html  css  js  c++  java
  • NET中class与struct的区别简析

    在没有class的面向过程的编程时代,struct是封装数据的利器,没它不行。但自从面向对象编程以来,class横空出世,大家高呼着“万事万物皆对象”,把class含在嘴里,握在手里,基本上使用class可以替代struct的任何场合。但是各位不要忘了“存在必有其价值”,所以struct还是有其作用和优势的地方的,要知道如何恰到好处的使用,就需先彻底了解二者的区别。

     

        很多时候一提起class和struct,可能很多初学朋友看不出它们兄弟俩有啥区别,的确语法几乎相同,但其本质却截然不同:class是引用类型,struct是值类型,也就是说在内存中存储方式有别,由此产生的一系列差异性。所以只有深刻的理解内存分配的相关内容,才能更好的驾驭。

        class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、构造函数、索引器、事件等。在.NET中,所有的类都继承自System.Object类,是一种引用类型,也就是说,当我们new出一个类的实例时,对象保存了该实例实际数据的引用地址,而对象的值保存在托管堆中。

     

        struct(结构)是一种值类型,用于将一组相关的信息变量组织成为一个单一的变量实体。所有的结构都继承自System.ValueType类,是一种值类型,我们可以像使用int和char一样去使用struct。struct实例分配在线程的堆栈上,它本身存储了值,而不是指向该值的指针。

     

    了解了class和struct的本质,我们可以通过分析和实验来总结二者的区别了:

    (1)关于实质:class是引用类型,struct是值类型
    (2)关于职能:class是行为的封装,用来表述对象,而struct是数据的封装,用来储存数据
    (3)关于继承:class支持继承自类和接口;而struct只能支继承接口。struct不能从class继承,也不能作为class的基类。
    (4)关于构造函数:class可以声明无参构造函数,可以声明析构函数;而struct只能声明带参数构造函数,且不能声明析构函数。
    (5)关于实例化:class要使用new关键字;而struct可以不使用new关键字,struct在声明时就进行了初始化过程,所有的成员变量均默认为0或null。
    (6)关于抽象:class可以实抽象类(abstract),可以声明抽象函数;而struct不能。
    (7)关于重载:class可以声明protected成员、virtual成员、sealed成员和override成员;而struct不可以,但是值得注意的是,struct可以重载System.Object的3个虚方法,Equals()、ToString()和GetHashTable()。
    (8)关于比较:两个class的比较有Equals和==两种,即值相等和引用相同;而两个struct可以直接通过==来判断。
    (9)关于销毁:class实例由垃圾回收机制来保证内存的回收处理;而struct变量使用完后立即自动解除内存分配。
    (10)关于参数传递:class变量是以按址方式传递;而struct变量是以按值方式传递的。

     

        既然class几乎可以完全替代struct来实现所有的功能,那么struct还有存在的必要吗?至少在以下情况下,我们应该考虑使用struct来代替class:

        实现一个用于存储数据的结构时,可以考虑struct。
        考虑与某些非托管代码通信的兼容性问题时,可以考虑struct。

    所有这些是struct有一席之地的理由,当然也许还有其他的更多说法,只是我不知道罢了。


    引用一个经典示例

    (1)定义接口

     interface IPerson{
    void GetSex();
    }

    (2)定义类

        public class Person
        {
            public Person()
            {
            }

            public Person(string name, int age)
            {
                _name = name;
                _age = age;
            }

            private string _name;

            public string Name
            {
              get { return _name; }
              set { _name = value; }
            }

            private int _age;

            public int Age
            {
              get { return _age; }
              set { _age = value; }
            }
        }

    (3)定义结构

        //可以继承自接口,不可继承类或结构
        struct Family: IPerson
        {
            public string name;
            public int age;
            public bool sex;
            public string country;
            public Person person;

            //不可以包含显式的无参构造函数和析构函数
            public Family(string name, int age,

                      bool sex, string country, Person person)
            {
                this.name = name;
                this.age = age;
                this.sex = sex;
                this.country = country;
                this.person = person;
            }

            //不可以实现protected、virtual、sealed和override成员
            public void GetSex()
            {
                if (sex)
                    Console.WriteLine(person.Name + " is a boy.");
                else
                    Console.WriteLine(person.Name + " is a girl.");
            }

            public void ShowPerson()
            {
                Console.WriteLine("This is {0} from {1}",

                                new Person(name, 22).Name, country);
            }

            //可以重载ToString虚方法
            public override string ToString()
            {
                return String.Format("{0} is {1}, {2} from {3}",

                    person.Name, age, sex ? "Boy" : "Girl", country);
            }
        }

        本文关于 class和struct的讨论到此为止,在.NET中,关于class和struct的讨论将涉及到对引用类型和值类型的认识,并且进一步将触角伸向变量内存分配这一高级主题,所以我们有必要来了解其运行机制,把握区别和应用场合,以便在平常的系统设计中把握好对这一概念层次的内容。

  • 相关阅读:
    Chrome浏览器网页截全屏算法以及实现
    去除scons构建动态库的前缀lib
    Javascript的继承
    win7 VS2008 ffmpeg release 版本崩溃 0x00905a4d 处未处理的异常
    shell脚本获取随机数random
    iOS navigationbar添加实现
    TableView中改变Button按钮状态
    将TableView的中的Label和Cell行数绑定
    build diff: /../Podfile.lock: No such file or directory
    initramfs-tools ... update-initramfs: Generating /boot/initrd.img-3.14-kali1-amd64 mktemp: failed to create directory via template `/var/tmp/mki
  • 原文地址:https://www.cnblogs.com/tangself/p/1621416.html
Copyright © 2011-2022 走看看