c#类与结构体区别

26 篇文章 1 订阅

终于写到这里了!下面就是我们大家期待已久的内容了!结构体与类的区别;希望通过我下面的讲解,对大家能够有所帮助,同时文章中有不足之处,大家多多指出哦!感激不尽!!!
这篇主要以代码和简单文字说明来阐述它们的异同之处。

1.关键字不同
定义类使用关键字class ;定义结构使用关键字struct。相信这个大家都知道吧!

   //关键字struct
  struct Mystruct
    {

   //结构内容
    }

   //关键字class
    class MyClass
    {
    //类内容
    }

2.在语法上其实类和结构有着很多相似的地方.但是又有不同之处。

 struct Mystruct
    {
        private string name = "菜鸟";
        private int age = 26;
        public void MyMethod()
        {
            Console.WriteLine("Name:{0};Age:{1} ", this.name, this.age);

        }

    }

    class Program
    {

        private   string name="菜鸟"; 
        private   int age=26;
        public void MyMethod()
        {
            Console.WriteLine("Name:{0};Age:{1} ",this.name ,this .age);

        }


        static void Main(string[] args)
        {

        }
    }

这代码虽然看不出来错误;但是大家看下面的图片;这里写图片描述
很明显结构体中编译不通过啦!这是为什么呢?请看错误类型:
发生错误
很明显:这是结构体中与类的一个区别啦!
也就是说:在结构中字段初始化语句是不允许的。会出现编译错误。而类中是可以的哦!但是注意啦!类中这样的写法也是错误的啦!

 public string name; 
        name="菜鸟";

3.关于构造函数.
首先,关于隐式构造函数.我们知道,在类中如果我们没有为类写任意的构造函数,那么C#编译器在编译的时候会自动的为这个类生成一个无参数的构造函数.我们将这个构造函数称之为隐式构造函数 但是一旦我们为这个类写了任意的一个构造函数的时候,这个隐式的构造函数就不会自动生成了.编译器就会使用我们自己的构造函数了。而且类中的构造函数显示声明是可以是无参数的或者是带有多个参数的重载的都可以。
但是在结构中,就不是这样了,在结构中隐式的构造函数无论如何都存在。并且不允许我们显示声明无参数的构造函数,必须带有参数。
首先是声明一个无参数的构造函数:

    struct Mystruct
    {
        private string name;
        private int age;
        public Mystruct()
        {


        }
        public void MyMethod()
        {
            Console.WriteLine("Name:{0};Age:{1} ", this.name, this.age);

        }

    }

    class Program
    {

        public string name = "菜鸟";
        private int age = 26;
        public Program()
        {

        }

        public void MyMethod()
        {
            Console.WriteLine("Name:{0};Age:{1} ",this.name ,this .age);

        }


        static void Main(string[] args)
        {

        }
    }

这里写图片描述
我们可以清晰的看到在结构体中声明无参数的构造函数会出错。而类中不会。这也是它们二者的区别。我们接着往下看:

 struct Mystruct
    {
        private string name;
        private int age;
        public Mystruct(string name,int age)
        {


        }
        public void MyMethod()
        {
            Console.WriteLine("Name:{0};Age:{1} ", this.name, this.age);

        }

    }

这里写图片描述
可以看出,如果我们虽然声明了不是无参数的构造函数,但是没有完全对字段赋值,编译器同样也是不通过的,而类则无次限制哦!
下面这样写就是对的啦

 struct Mystruct
    {
        private string name;
        private int age;
        public Mystruct(string name,int age)
        {
            this.name = name;
            this.age = age;

        }
        public void MyMethod()
        {
            Console.WriteLine("Name:{0};Age:{1} ", this.name, this.age);

        }

    }

下面我们看看类中是否可以声明多个构造函数呢?

class Program
    {

        public string name = "菜鸟";
        private int age = 26;
        public Program()
        {

        }
        public Program(int age)
        {

        }
        public Program(int age, string name)
        {

        }
        public void MyMethod()
        {
            Console.WriteLine("Name:{0};Age:{1} ",this.name ,this .age);

        }
    }

答案当然是可以的啦!这就是方法重载嘛!!!
在结构中:隐式的无参数的构造函数在结构中无论如何都是存在的,所以程序员不能手动的为结构添加一个无参数的构造函数.而类中手动添加后就会覆盖掉以前的无参数的构造函数哦!你们明白了没?
在结构体的构造函数中,必须要为结构体的所有字段赋值。

4.关于创建对象的方式:
我们知道类中创建对象都是通过new关键字来实例化出对象的。很简单的啦!

 static void Main(string[] args)
        {
           //创建类的对象p;
            Program p = new Program();
        }

而创建结构体对象可以不使用new关键字.直接声明一个变量就可以.但是这样的话,结构体对象中的字段是没有初始值的,所以在使用字段之前必须要为这个字段赋值.

  static void Main(string[] args)
        {
            Program p = new Program();
            Mystruct my;
            Console.WriteLine(my.name );//编译错误

        }

这里写图片描述
如果我们的字段在结构中没有赋值的话,会出现编译错误。
原因很简单.因为声明的时候就不能给初始值,虽然构造函数中为对象的字段赋值,但是此种方式创建结构体对象,没有调用构造函数,所以必须要程序员在使用之前手动赋值。下面这样就可以啦!

 static void Main(string[] args)
        {
            Program p = new Program();
            Mystruct my;
            my.name = "菜鸟";
            Console.WriteLine(my.name );

        }

当然了,你也可以像创建类的对象一样来为结构体赋值啦!
使用new关键字来创建,与不使用new关键字创建不同的是,通过使用new关键字创建结构体对象后,这个结构体对象的字段就已经有值了.原因是new关键字调用了构造函数,而结构体构造函数要求必须要为所有的字段赋值.

static void Main(string[] args)
        {
            Program p = new Program();
            Mystruct my = new Mystruct();
            Console.WriteLine(my.name );


        }

虽然我这里面并没有给我的构造函数赋值,但是系统会默认调用构造函数,并赋值为null的。这里是创建对象的不同啦!!!

5.继承时候的不同:
结构体不能从另外一个结构或者类继承,但是可以实现接口.

struct Mystruct:Program 
    {
        public  string name;
        private int age;
        public Mystruct(string name,int age)
        {
            this.name = name;
            this.age = age;

        }
        public void MyMethod()
        {
            Console.WriteLine("Name:{0};Age:{1} ", this.name, this.age);

        }

    }

这里写图片描述
我们发现这样我们的结构体不能继承类;会出现编译错误。而且错误类型为接口,所以我们的结构体可以进行接口继承啦!

6.本质区别:结构体是值类型 ,类是引用类型。
结构体是值类型,当其作为一个局部变量的时候,变量是存储在栈空间中的,其对象的字段直接存储在这个变量中的.与引用类型的类不一样,引用类型的变量中存储的是对象在堆空间中的地址,所以当我们传递一个引用类型的变量的时候,其实传递的是变量的值(对象的地址)即指向对象的引用(可以叫栈指针(但是微软对于c#方面一直弱化指针概念,个人认为知道指针会方便理解的,有兴趣的可以学学c++)) 传递完以后 对变量的修改会影响到另外一个变量指向的对象的值.
7.结构体无析构函数,而类有析构函数。
原因呢?还是很简单啊!因为类是引用类型,存储在堆上面,析构函数在释放内存时调用的,由我们的GC垃圾回收器去调用它的。是存储在堆上面的,而我们的结构体是值类型啊!所以压根不会由析构函数啊!要它干什么呢?嘿嘿!这样是不是可以更好的去理解呢???
8.最后说说什么时候使用它们吧!
结构存储在栈中,而栈有一个特点,就是空间较小,但是访问速度较快,堆空间较大,但是访问速度相对较慢.所以当我们描述一个轻量级对象的时候,可以将其定义为结构来提高效率当描述一个重量级对象的时候,我们知道类的对象是存储在堆空间中的,我们就将重量级对象定义为类. 他们都表示可以包含数据成员和函数成员的数据结构。与类不同的是,结构是值类型并且不需要堆分配。结构类型的变量直接包含结构的数据,而类类型的变量包含对数据的引用(该变量称为对象)。
希望这三篇博客能够对你们有点帮助啦!
文章写的比较仓促,不足之处,请多多指教啦!欢迎评论交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值