龙空技术网

C#编程零基础到入门学习-C# 结构体(Struct)(4-11)

天道格律随笔 1172

前言:

此时各位老铁们对“带参构造函数和无参构造函数的区别”大体比较关怀,你们都需要了解一些“带参构造函数和无参构造函数的区别”的相关文章。那么小编同时在网络上搜集了一些对于“带参构造函数和无参构造函数的区别””的相关文章,希望大家能喜欢,大家一起来了解一下吧!

在C#中,struct是表示数据结构的值类型数据类型。 它可以包含参数化构造函数、静态构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型

参数化构造函数、静态构造函数、字段、方法、属性、索引器、事件和嵌套类型等又引出了这些概念,不用着急理解,后面都会陆续学到。

**逐步在填坑,也在持续挖坑。。。。学习的时候不是一直往后学,也是需要回顾前面所学习的知识点,前面有些知识点、概念都只是提了下,并没有详细进行写,后面都会有详细的讲解**

struct 可以用于保存不需要继承的小数据值,例如坐标点,键值对和复杂的数据结构。

在C#中,结构体(Struct)是一种轻量级的数据类型,用于封装一组相关的数据成员。它与类(Class)类似,但具有一些区别和特性。

首先,结构体是值类型(Value Type),而类是引用类型(Reference Type)。这意味着当创建一个结构体实例时,会在内存中为这个实例分配空间,并且每个实例都具有自己的数据副本。而对于类,实例实际上是指向同一个对象的引用,多个引用可以指向同一个对象。

先认识一个简单的结构体:

示例代码:

struct Person  {      public string Name;      public int Age;      public string Address;  }

完整示例代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace StructType{    internal class Program    {        struct Person        {            public string Name;            public int Age;            public string Address;        }        static void Main(string[] args)        {            Person p = new Person();//是不是感觉跟前面的文章中的示例中的“类”的用法很像。            p.Name = "ZhangSan";            Console.WriteLine(p.Name);            Console.WriteLine(p.Age);//思考下为啥会是0            Console.WriteLine(p.Address);//这个应该是啥?        }    }}//运行下看看结果

注意看Struct的位置

运行结果

在这个示例中,我们定义了一个名为Person的结构体,它包含了三个公共成员:NameAgeAddress。这些成员可以是任何有效的C#数据类型,包括基本数据类型、引用类型、其他结构体等。

创建坐标系结构示例代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace CoordinateStruct{    internal class Program    {        static void Main(string[] args)        {            Coordinate point = new Coordinate();            Console.WriteLine(point.x); //输出:0              Console.WriteLine(point.y); //输出:0            point.y = 10;            point.x = 10;            Console.WriteLine(point.x); //输出:10              Console.WriteLine(point.y); //输出:10        }//仔细观察赋值和不赋值的区别    }    struct Coordinate    {        public int x;        public int y;    }}

上面,使用new关键字创建一个 Coordinate(坐标) 结构的对象。它调用结构的默认无参数构造函数,该构造函数将所有成员初始化为指定数据类型的默认值,默认为0

如果声明一个 struct 类型的变量而不使用 new 关键字,则它不调用任何构造函数,因此所有成员都保持未赋值状态。因此,在访问每个成员之前,必须为它们分配值,否则会产生编译时错误。

不使用 new 关键字创建结构如下示例代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace CoordinateStruct{    internal class Program    {        static void Main(string[] args)        {            Coordinate point;                      //Console.Write(point.x); // 编译时错误 ,先注释掉了。            point.y = 10;            point.x = 10;            Console.WriteLine(point.x); //输出:10              Console.WriteLine(point.y); //输出:10        }//仔细观察赋值和不赋值的区别    }    struct Coordinate    {        public int x;        public int y;    }}

错误示例

下面的一些示例对新手来说稍微有些难度了,不要着急,能看懂就看,看不懂可以暂时跳过这个部分,等把所有基础学完了,再回过头看这部分代码,把构造函数、析构函数、类、方法、虚方法、传参等相关知识都学完了,再回来看,会有不一样的感受,不要着急,另外在练习过程中逐步增加英语的词汇储备,善于使用工具。

结构构造函数-结构的方法和属性

结构(struct)不能包含无参数构造函数。它只能包含参数化构造函数或静态构造函数。

struct(结构)可以包含属性、自动实现的属性、方法等,与类相同。

带有构造函数和方法的结构体示例:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace StructFunction{    internal class Program    {        static void Main(string[] args)        {            Person person = new Person("ZhangSan",28,"HeNan");//传入参数            string info;            person.GetInfo(out info);//调用方法            Console.WriteLine(info);//输出            Console.WriteLine(person.Name);            Console.WriteLine(person.Age);            Console.WriteLine(person.Address);         }    }    struct Person    {        public string Name;        public int Age;        public string Address;        public Person(string name, int age, string address)//有参数的构造函数        {            this.Name = name;            this.Age = age;            this.Address = address;        }        public void GetInfo(out string info)//方法        {            info = $"{Name}, {Age}, {Address}";//GetInfo方法,用于将结构体的信息格式化为字符串        }    }}

在这个示例中,我们添加了一个带有参数的构造函数,用于初始化结构体的成员。还添加了一个GetInfo方法,用于将结构体的信息格式化为字符串。

上述示例讲解:这是一个公共方法,名为GetInfo。它有一个out参数,名为info,类型为stringout参数要求调用者在调用方法时提供一个可写的变量,以便方法可以将结果写入该变量。

info = $"{Name}, {Age}, {Address}";:这行代码使用字符串插值(string interpolation)将结构体的成员Name、Age和Address格式化为一个字符串,并将结果赋值给info。

在这个示例中,我们创建了一个名为personPerson结构体实例,并调用其GetInfo方法,将结果存储在变量info中。最后,我们将结果打印到控制台。

运行结果

上述代码,包含参数,可以自己调参,然后运行观察结果,再进行逐句调试,看看程序的执行过程。

需要注意的是,结构体有一些特定的规则和限制:

结构体不能是抽象的,也不能包含抽象方法虚方法结构体不能包含显式的默认构造函数(无参数的构造函数)。它们可以包含一个带有参数的构造函数,但必须至少有一个参数。结构体的大小必须是其成员大小的总和。这意味着结构体的成员不能包含任何额外的内存开销,例如虚函数表或对象头。结构体可以隐式地转换为其他类型,例如将一个结构体实例赋值给一个具有相同数据成员的类实例。这种转换称为装箱和拆箱。但是,装箱和拆箱会引入额外的性能开销,因此在使用结构体时需要谨慎考虑。装箱和拆箱后面会学到。结构体可以包含静态成员,但不能包含静态构造函数。静态构造函数仅适用于类。

结构体中的静态构造函数示例代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace StructStaticFunction{    internal class Program    {        static void Main(string[] args)        {            Coordinate point = Coordinate.GetOrigin();            Console.WriteLine(point.x); //输出:0              Console.WriteLine(point.y); //输出:0        }    }    struct Coordinate    {        public int x;        public int y;        public Coordinate(int x, int y)        {            this.x = x;            this.y = y;        }        public static Coordinate GetOrigin()        {            return new Coordinate();        }    }}

运行结果

必须在参数化构造函数中包含该结构的所有成员,并将其分配给成员;否则,如果任何成员保持未分配状态,C#编译器将给出编译时错误。

结构的方法和属性示例代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace StructMethodProperties{    internal class Program    {        static void Main(string[] args)        {            Coordinate point =new Coordinate();            point.SetOrigin();            Console.WriteLine(point.x); //输出:10              Console.WriteLine(point.y); //输出:20        }    }    struct Coordinate    {        public int x { get; set; }        public int y { get; set; }        public void SetOrigin()        {            this.x = 10;//赋值了            this.y = 20;//赋值了        }    }}

运行结果

结构事件

结构可以包含事件通知有关某些操作。

事件示例代码:

事件声明部分代码:

struct Coordinate{    private int _x, _y;    public int x     {        get{            return _x;        }        set{            _x = value;            CoordinatesChanged(_x);        }    }    public int y    {        get{            return _y;        }        set{            _y = value;            CoordinatesChanged(_y);        }    }    public event Action<int> CoordinatesChanged;}

事件处理部分代码:

static void Main(string[] args)    {        Coordinate point = new Coordinate();                point.CoordinatesChanged += StructEventHandler;        point.x = 10;        point.y = 20;    }//只赋给x、y单个值,如果赋予多个值呢?    static void StructEventHandler(int point)//事件处理方法    {        Console.WriteLine("坐标更改为 {0}", point);//输出到控制台变更的坐标    }

完整示例代码:

using System;using System.Collections.Generic;using System.Linq;using System.Security.Cryptography.X509Certificates;using System.Text;using System.Threading.Tasks;namespace StructIncident{    internal class Program    {        static void Main(string[] args)        {            Coordinate point = new Coordinate();            point.CoordinatesChanged += StructEventHandler;            point.x = 10;//赋值            point.y = 20;//赋值            point.x = 30;//赋值            point.y = 40;//赋值        }        static void StructEventHandler(int point)        {            Console.WriteLine("坐标更改为 {0}", point);        }    }    struct Coordinate    {        private int _x, _y;        public int x        {            get            {                return _x;//字段            }            set            {                _x = value;                CoordinatesChanged(_x);            }        }        public int y//变量        {            get            {                return _y;//字段            }            set            {                _y = value;//字段                CoordinatesChanged(_y);            }        }        public event Action<int> CoordinatesChanged;        /*        event:关键字,用于声明一个事件        Action<int>:这是一个泛型委托,表示该事件处理程序接受一个整数类型的参数,并且不返回任何值        CoordinatesChanged:这是事件的名称。        上面的结构包含coordinateChanged事件,当 x 或 y 坐标发生变化时将引发该事件。        */    }}

运行结果

struct是值类型,因此它比类对象快。每当您只想存储数据时,请使用struct。通常,结构适用于游戏编程。但是,与结构相比,传输类对象更容易。因此,当您通过网络或其他类传递数据时,请不要使用struct。

总结一下struct 可以包括构造函数,常量,字段,方法,属性,索引器,运算符,事件和嵌套类型。struct 不能包含无参数构造函数或析构函数。struct 可以实现与类相同的接口。struct 不能继承另一个结构或类,也不能作为一个类的基类。struct 不能将成员指定为抽象成员,密封成员,虚拟成员或受保护成员。

这个示例包含的内容有点多,涉及到的知识点也多,有学过的,有新的,不要着急,后面都会学到。

标签: #带参构造函数和无参构造函数的区别 #struct 析构函数