首页 > 编程语言 >C# 探险之旅:第四十七节 - 结构体(Struct)—— 当类说:“嘿,我也有个精简版!”

C# 探险之旅:第四十七节 - 结构体(Struct)—— 当类说:“嘿,我也有个精简版!”

时间:2024-12-16 16:27:21浏览次数:9  
标签:当类 Console Struct C# Age int WriteLine public 结构

嘿,探险家们!欢迎再次踏上C#的神秘之旅。今天,我们要聊的不是什么远古遗迹,也不是什么魔法咒语,而是一个超级实用、却又经常被忽略的小家伙——结构体(Struct)。想象一下,如果类是那个全能但稍显笨重的瑞士军刀,那么结构体就是那把轻巧、锋利的小刀,专门用来干些简单直接的活儿。

什么是结构体?

结构体,英文名叫Struct,听起来就像是“建造”或“结构”的意思,对吧?没错,它就是用来构建一些简单数据结构的。你可以把它想象成类的“迷你版”或者“精简版”。就像你有个大房子(类)可以住很多人,但有时候你只需要一个帐篷(结构体)来快速搭个营地,简单过夜。

结构体的特点
  1. 值类型:不同于类是引用类型,结构体是值类型。这意味着当你把一个结构体传给另一个方法时,它是直接复制过去的,而不是传递一个引用。就像是给你朋友一个苹果的复印件,而不是原件。

  2. 存储在栈上:因为它们是值类型,所以结构体通常存储在栈上,这使得访问速度非常快,就像是直接从口袋里拿东西一样方便。

  3. 不能继承:结构体不能继承其他结构体或类,也不能被其他结构体或类继承。这就像是说:“我就是我,是颜色不一样的烟火。”

  4. 适合小数据集合:结构体最适合用来存储一些小的、紧密相关的数据。比如,你想存储一个人的姓名、年龄和身高,用结构体就非常适合。

定义一个结构体

定义一个结构体超级简单,就像这样:

// 定义一个简单的结构体:Point
public struct Point
{
    // 字段
    public int X;
    public int Y;

    // 构造函数
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    // 方法
    public void Display()
    {
        Console.WriteLine($"点的坐标: ({X}, {Y})");
    }
}

在这个例子中,Point是一个结构体,它有两个字段XY,一个构造函数用于初始化这些字段,以及一个Display方法用于显示点的坐标。

结构体VS类:一场友好的辩论

  • 结构体:“我轻量级,速度快,适合小任务!”
  • :“我功能全面,能继承,能多态,适合大项目!”
  • 结构体:“我不需要垃圾回收,因为我不在堆上分配内存!”
  • :“我可以有复杂的对象关系,你行吗?”

结构体 vs 类:谁更适合?

结构体和类有很多相似之处,但它们也有一些关键的区别。为了更好地理解这些区别,我们可以把结构体比作一个小工具箱,而类比作一个大仓库。

结构体的特点:
  • 值类型:结构体是值类型,这意味着它们存储在栈上(或嵌入到其他值类型中),并且每次传递时都会复制一份。这使得结构体非常适合存储小型、频繁使用的数据。

Point p1 = new Point(10, 20);
Point p2 = p1; // p2 是 p1 的副本
p2.X = 30;
Console.WriteLine(p1.X); // 输出 10
Console.WriteLine(p2.X); // 输出 30
  •  轻量级:结构体通常比类更轻量级,因为它们不需要额外的内存管理开销(如垃圾回收)。这使得结构体非常适合用于表示简单的、不可变的数据结构。
  • 不可变性:结构体默认是不可变的(除非你显式地添加修改器),这意味着一旦创建了结构体实例,就不能轻易修改它的字段。这有助于避免意外的状态变化,提高代码的安全性。

  • 性能优势:由于结构体是值类型,它们在某些情况下可以提供更好的性能,尤其是在频繁创建和销毁的情况下。例如,在循环中创建大量的小对象时,使用结构体会比使用类更高效。

类的特点:
  1. 引用类型:类是引用类型,意味着它们存储在堆上,并且多个变量可以共享同一个对象。这使得类适合用于表示复杂、长期存在的对象。

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Person person1 = new Person { Name = "Alice", Age = 30 };
Person person2 = person1; // person2 和 person1 指向同一个对象
person2.Age = 31;
Console.WriteLine(person1.Age); // 输出 31
Console.WriteLine(person2.Age); // 输出 31
  • 可变性:类通常是可变的,你可以随时修改对象的状态。这使得类适合用于表示需要频繁更新的对象。

  • 继承和多态:类支持继承和多态,这意味着你可以创建层次化的对象模型,并利用面向对象编程的强大功能。结构体不支持继承(除了实现接口),因此它们更适合用于表示简单的、独立的数据结构。

什么时候使用结构体?

结构体最适合用于表示小型、不可变的数据结构,尤其是那些频繁创建和销毁的对象。以下是一些常见的使用场景:

  • 几何形状:表示点、矩形、圆形等几何形状时,结构体是非常合适的选择。这些数据结构通常很小,且不需要复杂的逻辑。

public struct Rectangle
{
    public int Width;
    public int Height;

    public int Area => Width * Height;

    public void Display()
    {
        Console.WriteLine($"矩形的宽度: {Width}, 高度: {Height}, 面积: {Area}");
    }
}
  • 数学运算:表示复数、向量、矩阵等数学概念时,结构体可以提供高效的性能和清晰的语义。 
public struct Complex
{
    public double Real;
    public double Imaginary;

    public Complex(double real, double imaginary)
    {
        Real = real;
        Imaginary = imaginary;
    }

    public static Complex operator +(Complex a, Complex b)
    {
        return new Complex(a.Real + b.Real, a.Imaginary + b.Imaginary);
    }

    public void Display()
    {
        Console.WriteLine($"{Real} + {Imaginary}i");
    }
}
  •  数据库记录:表示简单的数据库记录时,结构体可以提供轻量级的存储方式,避免不必要的内存开销。
public struct UserRecord
{
    public int Id;
    public string Username;
    public string Email;

    public void Display()
    {
        Console.WriteLine($"用户ID: {Id}, 用户名: {Username}, 邮箱: {Email}");
    }
}

实例挑战:

为了更好地理解这些概念,让我们来看一个幽默的例子:

// 使用结构体
Cat myCat = new Cat("Whiskers", 3);
myCat.Meow(); // 输出: Whiskers 喵喵~ (年龄: 3)

// 复制结构体
Cat anotherCat = myCat;
anotherCat.Age = 5;

myCat.Meow(); // 输出: Whiskers 喵喵~ (年龄: 3)
anotherCat.Meow(); // 输出: Whiskers 喵喵~ (年龄: 5)

// 定义一个结构体:Cat
public struct Cat
{
    public string Name;
    public int Age;

    public Cat(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public void Meow()
    {
        Console.WriteLine($"{Name} 喵喵~ (年龄: {Age})");
    }
}

在这个例子中,Cat是一个结构体,它包含猫的名字和年龄,并且有一个Meow方法让猫发出声音。由于结构体是值类型,anotherCatmyCat的一个副本,修改anotherCat的年龄不会影响myCat的年龄。

小结

结构体是C#中一种轻量级的、值类型的容器,它非常适合用于表示小型、不可变的数据结构。通过使用结构体,你可以编写更高效、更简洁的代码,避免不必要的内存开销。希望这段探险之旅让你对结构体有了新的认识,也希望能为你的编程旅途增添一些乐趣。继续前行,更多精彩的C#探险等着你!

标签:当类,Console,Struct,C#,Age,int,WriteLine,public,结构
From: https://blog.csdn.net/caifox/article/details/144511525

相关文章

  • C# 探险之旅:第四十四节 - 栈(Stack)和堆(Heap):一场内存管理的喜剧
    嘿,勇敢的探险家们!欢迎来到C#探险之旅的第四十二节!今天,我们要揭开内存管理界最神秘的二人组——栈(Stack)和堆(Heap)的面纱。栈(Stack)和堆(Heap)——这两个神秘的内存区域,它们就像是你家里的两个储物空间:一个整齐有序的小抽屉,另一个是杂乱无章的大仓库。理解它们的区别和用途,可以帮助......
  • P1570 KC 喝咖啡
    不在赘述题目了。这是一道典型的分数规划题目。可以参考一下https://oi-wiki.org/misc/frac-programming/的内容。这里主要讲一下笔者自己在做题时遇到的一些困惑。为什么可以二分我们以$x[i]=1$表示取第$i$种材料,$x[i]=0$表示不取。那么最后的答案会有$ans=\sum\frac{v[i]......
  • FastExcel 合并单元格(相当的行数据,进行合并)
    目录需求思路实现Excel导出单元格全量合并策略日期格式转换接口代码ServiceDTO使用FastExcel数据导出:官网:https://idev.cn/fastexcel/zh-CN需求信用代码、填报人,唯一时,将:信用代码、单位名称、填报人,进行row合并,并垂直居中对齐思路这边不需要做列合并,所以采用了RowWrite......
  • CSP 2024 游记
    \(\texttt{Day-INF}\)只考S。这gesp怎么只能免一次啊,有点坑。洛谷模拟赛没打到1=线,联考次次挂分,慌得一批。考得比去年低就好玩了。运动会和csp冲了一天。好消息:不用排练开幕式了。坏消息:第二天还得去。\(\texttt{Day-5}\)福建师大附中润德楼50250号。感觉状态有......
  • 2024《毒液3》最后一舞 Venom: The Last Dance 【4K超清】电影 附网盘资源链接
    导演凯莉·马塞尔主演汤姆·哈迪/切瓦特·埃加福/朱诺·坦普尔/瑞斯·伊凡斯/斯蒂芬·格拉汉姆/佩吉·陆/安迪·瑟金斯/克拉克·巴茨科/阿兰娜·乌巴赫/克里斯托·费尔南德斯/杰瑞德·亚伯拉汉姆森/哈拉·芬利/达什·麦克劳德/瑞德·斯科特/杰克·......
  • CMU_15445_P3_Part1
    CMU_15445_P3_Part1这部分主要是实现一些基本的Plan_Node的Executor,我们可以首先通过一个列子来看,就是ProjectionPlan_Node的例子.Projection类型的PLAN_NODE是作为有条件的SELECT语句或者嵌套的SELECT语句的根节点,例如:SELECTa,bFROMt1WHEREc>10;......
  • DeprecationWarning: Callback API version 1 is deprecated, update to latest versi
    背景说明        最近在使用MQTT进行发送消息的时候,每次运行都会弹出这个红色的警告,虽然不影响运行,但是看起来怪怪的,于是乎想顺手解决一下,自己使用的mqtt服务器是mosquitto。具体的警告提示如下:问题分析及解决        在Python中使用MQTT时,如果你收到......
  • [SAP ABAP] 上传CSV文件到内表
    CSV文件数据测试数据.csv上传csv文件到内表的开发步骤:①选择屏幕以及上传文件的相关参数设置②获取上传的CSV文件数据行自定义的csv文件,编码格式是utf-8,但是使用GUI_UPLOAD函数读取文件数据,会出现中文乱码,因此需要给形参codepage指定编码格式'8400'③......
  • pikachu靶场SSCR漏洞测试报Warning: file_get_contents()警告信息
    1.这个警告Warning:file_get_contents()是PHP中的一个常见错误。可能的原因有很多。2.路径问题如果调用file_get_contents()时传递了一个文件路径,可能路径不正确或者文件不存在。确保文件路径正确且文件可访问。3.url问题如果传递的是URL,确保该URL是有效且可访问的......
  • LeetCode题练习与总结:连接词--472
    一、题目描述给你一个 不含重复 单词的字符串数组 words ,请你找出并返回 words 中的所有 连接词 。连接词 定义为:一个完全由给定数组中的至少两个较短单词(不一定是不同的两个单词)组成的字符串。示例1:输入:words=["cat","cats","catsdogcats","dog","dogcatsdog......