自学七--结构体

【概述】

C#中结构类型和类类型在语法上非常相似,他们都是一种数据结构,都可以包括数据成员和方法成员。结构体是值类型,直接包含它自己的数据,每个结构都保存自己的一份数据,修改每一个结构的数据都不会对其他结构的数据造成影响。

注意:

struct关键字修饰。

【结构体声明方式】

权限访问修饰符 struct 结构体类型名{
    /*结构体成员*/
    /*
        字段、
        属性、
        方法、
        ……
    */
}

eg:

// #region << 版 本 注 释 >>
// /*----------------------------------------------------------------
// // Copyright (C) 2019 极客部落
// // 版权所有。 
// //
// // 文件名:Program.cs
// // 文件功能描述:
// //
// // 
// // 创建者:GeekTribe
// // 时间:14:05
// //----------------------------------------------------------------*/
// #endregion
using System;
​
namespace MSN
{
    public struct PersonStruct
    {
        public string Name;
        public string MobilePhone;
        public DateTime Birthday;
    }
​
    class MainClass
    {
        public static void Main(string[] args){
            PersonStruct p1, p2;    //与类一样,但可以不new
            p1.Name = "张飞";
            p1.MobilePhone = "13553663108";
            p1.Birthday = DateTime.Now.AddYears(-10);
​
            p2 = p1;              //将p1的值赋给p2   
                                  //由于是值类型,因此赋值等于将全部值全部复制到p2的栈空间
​
            p2.Name = "关羽";     //修改p2的值看是否会影响p1
            Console.WriteLine(p1.Name);     //输出 张飞 没影响•
        }
    }
}

注意:

将一个结构变量赋值给另一个结构变量,就是把数据从一个结构复制到另一个结构。

【结构体构造函数与析构函数】

结构类型可以有实例构造函数和静态构造函数,但不能有析构函数。

【结构体实例构造函数】

结构体类型都有一个预定义的,没有参数的构造函数。此构造函数不允许删除和重定义,并且这个无参数的构造函数会一直存在,并不会因为定义了其他带参数的构造函数就消失。

注意:

  • 如果没有使用new运算符,是不可以使用数据成员的值(除非已显示地设置了该数据成员的值)和调用函数成员(除非所有数据成员均已经被赋值)。
  • 定义结构体构造函数时,也需要对所有的数据成员进行初始化。

eg:

// #region << 版 本 注 释 >>
// /*----------------------------------------------------------------
// // Copyright (C) 2019 极客部落
// // 版权所有。 
// //
// // 文件名:Program.cs
// // 文件功能描述:
// //
// // 
// // 创建者:GeekTribe
// // 时间:14:05
// //----------------------------------------------------------------*/
// #endregion
using System;
​
namespace MSN
{
    public struct PersonStruct
    {
        public string Name;
        public string MobilePhone;
        public DateTime Birthday;
​
        /*实例构造函数*/
        public PersonStruct(string _name, string _mp, DateTime _dt) {
            this.Name = _name;
            this.MobilePhone = _mp;
            this.Birthday = _dt;
        }
​
        public void Show() {
            Console.WriteLine("PersonStruct.Name = {0}, " +
                "PersonStruct.MobilePhone = {1}," +
                "PersonStruct.Birthday = {2}",
                this.Name, this.MobilePhone, this.Birthday);
        }
​
        public override string ToString()
        {
            return string.Format("PersonStruct.Name = {0}, " +
                "PersonStruct.MobilePhone = {1}," +
                "PersonStruct.Birthday = {2}", this.Name,
                this.MobilePhone, this.Birthday);
        }
    }
​
    class MainClass
    {
        public static void Main(string[] args){
            PersonStruct p1;    //与类一样,但可以不new••            
            p1.Name = "张飞";
            p1.MobilePhone = "13553663108";
            p1.Birthday = DateTime.Now.AddYears(-10);
​
            p1.Show();
​
            PersonStruct p2 = new PersonStruct("李云龙", "13315378765", DateTime.Now.AddYears(10));           
            Console.WriteLine(p2.ToString());
        }
    }
}

【结构体静态构造函数】

结构体类型也可以有静态构造函数,静态构造函数用于初始化静态数据成员。静态构造函数有如下特点:

1:静态构造函数不能使用任何访问修饰符

2:静态构造函数不能带有任何参数

3:静态构造函数只会执行一次

4:不能直接调用静态构造函数

5:程序员无法直接控制静态构造函数调用时机

6:静态构造函数不能访问实例成员

结构体的静态构造函数的触发规则:

  1、使用显式声明的构造函数进行初始化,使用默认的构造函数进行初始化不会触发。

  2、调用结构体的方法或访问结构体的静态数据成员(无论是读取还是赋值,访问实例数据成员不会触发CLR自动调用静态的构造函数)。

eg:

// #region << 版 本 注 释 >>
// /*----------------------------------------------------------------
// // Copyright (C) 2019 极客部落
// // 版权所有。 
// //
// // 文件名:Program.cs
// // 文件功能描述:
// //
// // 
// // 创建者:GeekTribe
// // 时间:14:05
// //----------------------------------------------------------------*/
// #endregion
using System;
​
namespace MSN
{
    public struct PersonStruct
    {
        //实例成员变量
        public string Name;
        public string MobilePhone;
        public DateTime Birthday;
​
        //静态成员变量
        public static int s_iNum = 100;
​
        /*实例构造函数*/
        public PersonStruct(string _name, string _mp, DateTime _dt) {
            this.Name = _name;
            this.MobilePhone = _mp;
            this.Birthday = _dt;
        }
​
        /*静态构造函数*/
        static PersonStruct() {
            //this.Name = "林耀东";//❌静态构造函数不能访问实例成员;
​
            s_iNum++;//静态成员变量
​
            Console.WriteLine("Static Constructor Function of PersonStruct");
        }
​
        //实例成员函数
        public void Show() {
            Console.WriteLine("PersonStruct.Name = {0}, " +
                "PersonStruct.MobilePhone = {1}," +
                "PersonStruct.Birthday = {2}",
                this.Name, this.MobilePhone, this.Birthday);
        }
​
        public static void SPrint() {
            Console.WriteLine("s_iNum = {0}", s_iNum);
        }
​
        //函数重写
        public override string ToString()
        {
            return string.Format("PersonStruct.Name = {0}, " +
                "PersonStruct.MobilePhone = {1}," +
                "PersonStruct.Birthday = {2}", this.Name,
                this.MobilePhone, this.Birthday);
        }
    }
​
    class MainClass
    {
        public static void Main(string[] args){
            /*使用显式声明的构造函数进行初始化,使用默认的构造函数进行初始化不会触发。*/
            PersonStruct p1 = new PersonStruct();
​
            PersonStruct p2 = new PersonStruct("李云龙", "13315378765", DateTime.Now.AddYears(10));•            
            Console.WriteLine(p2.ToString());
​
            /*调用结构体的方法或访问结构体的静态数据成员(无论是读取还是赋值,访问实例数据成员不会触发CLR自动调用静态的构造函数)。*/
            Console.WriteLine("s_iNum = {0}", PersonStruct.s_iNum);
            PersonStruct.SPrint();
        }
    }
}
​

【结构体继承性和多态性】

结构体直接派生自System.ValueType,间接派生自System.Object,但结构体是隐式密封的,不能作为基类再派生出其他的结构。

结构的特性:

  1、结构类型总是隐式密封的,因此在定义结构时不能使用sealed和abstract关键字;

  2、因为结构不能作为基类,结构的成员不能使用如下访问修饰符:protected和protected internal;

  3、结构的函数成员不能声明为abstract和virtual,但是可以使用override关键字,用以覆写它的基类System.ValueType中的方法。

9.2 运算符重载

C#里面也有运算符重载,主要是为了对自定义的类型使用某一个运算符。对于一元运算符,重载需要带一个类或结构类型作为参数;而二元运算符重载则需要带两个类或该类型的结构体。语法如下:

public static 类型 operator 重载的运算符(类型1,类型2)

从中可以看出,所有的运算符都应该为静态方法,且需要使用public关键字进行修饰。

// #region << 版 本 注 释 >>
// /*----------------------------------------------------------------
// // Copyright (C) 2019 极客部落
// // 版权所有。 
// //
// // 文件名:Program.cs
// // 文件功能描述:
// //
// // 
// // 创建者:GeekTribe
// // 时间:14:05
// //----------------------------------------------------------------*/
// #endregion
using System;
​
namespace MSN
{
    public struct Complex
    {
        public int real;
        public int imaginary;
        public Complex(int r, int c)
        {
            this.real = r;
            this.imaginary = c;
        }
​
        public static Complex operator +(Complex c1, Complex c2)
        {
            Complex result = new Complex();
            result.real = c1.real + c2.real;
            result.imaginary = c1.imaginary + c2.imaginary;
            return result;
        }
​
        public override string ToString()
        {
            return string.Format("{0}+{1}i", real, imaginary);
        }
    }
​
    class MainClass
    {
        public static void Main(string[] args){
            Complex num1 = new Complex(2, 4);
            Complex num2 = new Complex(3, 6);
            Complex sum = num1 + num2;
            Console.WriteLine("两个复数和为{0}", sum);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值