.NET学习资料
.NET学习资料
.NET学习资料
一、结构体的定义与基本使用
(一)定义结构体
在 C# 中,使用struct关键字来创建结构体。它就像是一个模板,能定义出符合特定需求的数据结构。比如,若要跟踪图书馆中书的信息,可定义如下Books结构体:
struct Books
{public string title;public string author;public string subject;public int book_id;
}
在这个结构体定义中,包含了表示书籍标题(title)、作者(author)、主题(subject)以及书籍编号(book_id)的成员变量,类型分别为string和int ,通过这些成员变量可以全面描述一本书的关键属性。
(二)结构体的使用示例
下面是一个完整展示结构体用法的程序示例:
using System;struct Books
{public string title;public string author;public string subject;public int book_id;
};public class testStructure
{public static void Main(string[] args){// 声明两个Books类型的结构体变量Book1和Book2Books Book1; Books Book2; // 为Book1的各个成员变量赋值Book1.title = "C Programming";Book1.author = "Nuha Ali";Book1.subject = "C Programming Tutorial";Book1.book_id = 6495407;// 为Book2赋值Book2.title = "Telecom Billing";Book2.author = "Zara Ali";Book2.subject = "Telecom Billing Tutorial";Book2.book_id = 6495700;// 打印Book1的详细信息Console.WriteLine("Book 1 title : {0}", Book1.title);Console.WriteLine("Book 1 author : {0}", Book1.author);Console.WriteLine("Book 1 subject : {0}", Book1.subject);Console.WriteLine("Book 1 book_id :{0}", Book1.book_id);// 打印Book2的详细信息Console.WriteLine("Book 2 title : {0}", Book2.title);Console.WriteLine("Book 2 author : {0}", Book2.author);Console.WriteLine("Book 2 subject : {0}", Book2.subject);Console.WriteLine("Book 2 book_id : {0}", Book2.book_id);Console.ReadKey();}
}
上述代码编译并执行后,输出结果如下:
Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700
从示例中能清晰看到,通过结构体变量可方便地访问和操作其内部各个成员变量,分别对不同书籍信息进行赋值和展示,体现了结构体在组织和管理相关数据方面的便利性。
二、C# 结构的特点
(一)丰富的成员类型
结构体不仅能存储简单数据,还可带有方法、字段、索引、属性、运算符方法和事件等多种成员类型。这使其能适用于表示各种轻量级数据,如坐标(包含 x 和 y 坐标值的结构体,搭配方法进行坐标运算等操作)、范围(定义包含起始值和结束值的结构体,以及判断是否包含某个值的方法等)、日期、时间等。
(二)构造函数相关限制与特性
结构体可以定义构造函数,但不能定义析构函数 。并且,结构体不能定义无参构造函数,无参构造函数(默认)由系统自动定义,且不能手动改变。例如:
struct Point
{public int X;public int Y;// 合法的有参构造函数public Point(int x, int y){X = x;Y = y;}// 以下是非法的无参构造函数定义,结构体不允许这样写// public Point()// {// }
}
(三)继承方面的限制
结构体不能继承其他的结构或类,也不能作为其他结构或类的基础结构。这意味着结构体在继承体系方面相对独立,更侧重于简单地封装和处理自身内部定义的数据和相关逻辑,不像类那样能通过继承扩展功能、实现多态等复杂的面向对象设计模式。
(四)接口实现能力
虽然结构体不能参与继承关系,但它具备实现一个或多个接口的能力。通过实现接口,结构体可以遵循接口中定义的契约,从而获得特定的行为和功能。例如,若定义一个包含计算面积方法的接口,结构体可以实现该接口来提供面积计算的具体实现。
(五)成员修饰符限制
结构体中的成员默认是public的,也可以使用其他访问修饰符,如private、protected等,但相比类,其使用场景和限制有所不同。例如,在结构体中使用private修饰成员时,需要通过属性或方法来访问这些私有成员,以确保数据的安全性和封装性。
(六)实例化与初始化特点
在实例化结构体时,可以使用构造函数进行初始化,也可以在声明后分别对成员进行赋值。例如:
Point p1 = new Point(10, 20);
Point p2;
p2.X = 30;
p2.Y = 40;
(七)内存分配与性能特点
结构体是值类型,通常在栈上分配内存(在某些情况下,如作为类的成员时,可能会随类一起在堆上分配)。这使得结构体在传递和使用时,是按值复制的,在处理小数据结构且频繁复制或传递时,性能表现较好,能减少内存分配和垃圾回收的开销。但如果结构体过大,值传递时会产生较大性能开销。
(八)可变性特点
结构体默认是可变的,即其成员的值可以在创建后被修改。不过,也可以通过将结构体设计为不可变(所有成员为只读或通过特定设计保证不可修改)来提高其在多线程环境中的安全性,避免数据竞争问题。
三、类 vs 结构
(一)值类型 vs 引用类型
结构体是值类型,在栈上分配内存(特殊情况除外),赋值或传递时是按值复制;类是引用类型,对象在堆上分配内存,赋值或传递时传递的是对象的引用。
(二)继承和多态性
结构体不支持继承,不能从其他结构体或类继承,也不能被其他结构体或类继承;类支持继承和多态,可以通过继承实现代码复用和多态行为。
(三)默认构造函数
结构体隐式地具有一个无参数的默认构造函数,将所有字段初始化为默认值,但不能手动定义无参构造函数;类可以显式地定义默认构造函数或其他构造函数。
(四)赋值行为
结构体赋值时,会创建一个新的副本,两个变量相互独立;类赋值时,只是复制引用,两个变量指向同一个对象,对其中一个变量的修改会影响另一个。
(五)传递方式
结构体作为方法参数传递时,是按值传递,方法内对参数的修改不会影响外部变量;类作为方法参数传递时,是按引用传递,方法内对参数的修改会影响外部变量。
(六)可空性
结构体本身不可空,但可以通过Nullable类型使其可空;类本身就是引用类型,默认可以为null。
(七)性能和内存分配
在处理小数据结构且频繁复制或传递时,结构体性能更好,内存使用更高效;对于大数据结构或需要复杂的对象层次和多态行为时,类更合适。因为结构体过大时,值传递开销大,且不支持继承和多态,无法满足复杂需求。