当前位置: 首页 > article >正文

C# 结构体介绍


.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和Book2
        Books 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。

(七)性能和内存分配

在处理小数据结构且频繁复制或传递时,结构体性能更好,内存使用更高效;对于大数据结构或需要复杂的对象层次和多态行为时,类更合适。因为结构体过大时,值传递开销大,且不支持继承和多态,无法满足复杂需求。


http://www.kler.cn/a/530987.html

相关文章:

  • ieee模版如何修改参考文献的格式以及多作者省略等
  • 全栈开发:使用.NET Core WebAPI构建前后端分离的核心技巧(一)
  • 数据库、数据仓库、数据湖有什么不同
  • FPGA 时钟多路复用
  • Python + Tkinter + pyttsx3实现的桌面版英语学习工具
  • 【Pytorch和Keras】使用transformer库进行图像分类
  • Maven的三种项目打包方式——pom,jar,war的区别
  • 【系统性能】2.1 整机卡顿初探
  • 兼容性测试笔记
  • selenium记录Spiderbuf例题C03
  • Macos编译openjdk因berkeley-db版本问题失败解决办法
  • 为什么命令“echo -e “\033[9;0]“ > /dev/tty0“能控制开发板上的LCD不熄屏?
  • 制造业设备状态监控与生产优化实战:基于SQL的序列分析与状态机建模
  • 【PyQt】超级超级笨的pyqt计算器案例
  • deepseek 本地化部署和小模型微调
  • 当前热门文生图大模型介绍与优缺点分析
  • Rust `struct`和 `enum`番外《哪吒、白蛇传?》
  • 嵌入式知识点总结 操作系统 专题提升(三)-并发与互斥
  • 使用React和Material-UI构建TODO应用的前端UI
  • 无人机飞行惯导系统技术详解
  • deepseek本地部署+结合思路
  • sql主从同步
  • Med-R2:基于循证医学的检索推理框架:提升大语言模型医疗问答能力的新方法
  • URL 和 URI 的区别
  • java命令详解
  • 二维前缀和:高效求解矩阵区域和问题