C#---结构与类

来源:互联网 发布:阿里云账号和淘宝账号 编辑:程序博客网 时间:2024/05/18 00:19

    结构体和类同样能够定义 字段,方法和 构造函数,都能实例化对象,这样看来结构体和类的功能好像是一样的了,实则不一样。

1.首先是语法定义上的区别

    定义 类 用关键字class,定义 结构 用关键字struct。

  //定义结构     public struct Person//定义一个person结构,含有三个字段 年龄,姓名,性别     {         public int _age;         public string _name;         public string _sex;     }    //定义类     public class School//定义一个School类,含有三个字段,年龄,姓名,性别     {          public int _age ;          public string _name;          public string _sex;     }


2.语法上两者很相似,但是还有细微之处的区别也需要知道。

    2.1 在结构中声明字段

        在结构中声明字段时,不允许给赋初值。会报错,如下:



    2.2 在类中声明字段

       在类中声明字段,可以为其赋初值。如下:

 //定义类     public class School//定义一个School类,含有三个字段,年龄,姓名,性别     {         public int _age = 20;         public string _name = "小王";         public string _sex="男";             }
        但是,不可以先定义字段,然后换行为其赋值,如下错误写法:

 //定义类     public class School//定义一个School类,含有三个字段,年龄,姓名,性别     {             //public int _age = 20;             //public string _name = "小王";         public string _sex;            _sex="男";         Console.writeline(_sex);     }
        错误示例图:


       有的同学可能有疑问了,为什么在结构中不可以赋初值在类中却可以呢?

    其实,定义类时,能为其赋初值,是因为微软已经在后台有代码来执行这一赋值过程了,后台代码把 public int _age = 20;这样的语句拆分开,先定义,在通过方法为其赋值。然后对于结构,微软没有给出这样的功能。

    C#编译器在编译的时候,如果我们声明字段的时候为字段赋值,那么为字段赋值的代码C#编译器在编译的时候会将赋值的代码放到构造函数中去,其实严格意义上来说,类的字段也是不能有初始值的.只不过微软在背后帮我们做了点事情,我们不知道而已.


    2.3 关于构造函数

        关于隐式构造函数.我们知道,在1个类中如果我们没有为类写任意的构造函数,那么C#编译器在编译的时候会自动的为这个类生成1个无参数的构造函数.我们将这个构造函数称之为隐式构造函数 但是一旦我们为这个类写了任意的1个构造函数的时候,这个隐式的构造函数就不会自动生成了.

        2.3.1 隐士构造函数

           在结构中,有默认的一个无参构造函数(隐士构造函数),当我们手动写一个有参构造函数时,默认的无参构造函数还存在

 public Person(int age, string name, string sex)  //为结构体写一个有参构造函数                {              this._age =age ;             this._name = name ;             this._sex = sex ;         }
   当我们使用new关键字创建结构体对象时,如下,提示有两个构造函数,一个是无参构造函数,一个是我们刚才写的有参构造函数。


如果我们是手动写一个无参构造函数呢?那就试试吧。。


结果出错了,隐式的无参数的构造函数在结构中无论如何都是存在的,不能手动的为结构添加1个无参数的构造函数.

        2.3.2 在结构体的构造函数中,必须要为结构体的所有字段赋值


这里就报错了,因为没有给_sex字段赋值。缺少“this._sex=sex;”


3.创建结构体对象的方式。

    3.1 创建结构体对象可以不使用new关键字。

        直接声明1个变量就可以.但是这样的话,结构体对象中的字段是没有初始值的,所以在使用字段之前必须要为这个字段赋值.因为声明的时候就不能给初始值,虽然构造函数中为对象的字段赋值,但是此种方式创建结构体对象,没有调用构造函数,所以必须要程序员在使用之前手动赋值。如下:

#region   定义个结构叫MyColor ,有三个成员,声明一个MyColor类型的变量,并对其赋值,使得MyColor可以表示红色        MyColor color;//创建结构体对象        color._red = 255;//为字段赋值        color._green = 0;        color._blue = 0;#endregion


如果这种方法创建结构体对象,不给字段赋值会怎么样呢?


    3.2 通过使用new关键字创建结构体对象

       通过使用new关键字创建结构体对象后。这个结构体对象的字段就已经有值了.原因不难理解,new关键字调用了构造函数,而结构体构造函数要求必须要为所有的字段赋值.

 //定义结构     public struct Person//定义一个person结构,含有三个字段 年龄,姓名,性别     {         public int _age;         public string _name;         public string _sex;         public Person(int age, string name, string sex)  //为结构体写一个有参构造函数                {             this._age = age;             this._name = name;             this._sex = sex;         }                  }     class Program     {         static void Main(string[] args)         {             Person p = new Person(16, "王志", "男");//使用有参构造函数             Console.WriteLine("性别{0},名字{1},年龄{2}", p._sex, p._name, p._age);             Console.ReadKey();         }     }
运行结果:


当我使用无参构造函数时:

//定义结构     public struct Person//定义一个person结构,含有三个字段 年龄,姓名,性别     {         public int _age;         public string _name;         public string _sex;         public Person(int age, string name, string sex)  //为结构体写一个有参构造函数                {             this._age = age;             this._name = name;             this._sex = sex;         }                  }     class Program     {         static void Main(string[] args)         {             Person p = new Person();//使用无参构造函数             Console.WriteLine("性别{0},名字{1},年龄{2}", p._sex, p._name, p._age);             Console.ReadKey();         }     }
 运行结果:


    所以,我们不难猜出.结构体的无参数的构造函数做了什么事情,在无参数的构造函数中为所有的字段赋值,值类型的字段赋值0,给引用类型的字段赋值null.

4. 结构是值类型,类是引用类型

    值类型的值存在“栈”里面,传值,不传地址; 引用类型地址存在堆里面,传地址,不传值。


0 0
原创粉丝点击