C#——类与结构

在未学习面向对象语言时,我常常将类比作一种结构体,其实类与结构体也确实很相似,类用来做函数的集合,结构用来做变量的集合,接下来将从几个角度刨析类与结构的不同。

类 vs 结构

类和结构在设计和使用时有不同的考虑因素,类适合表示复杂的对象和行为,支持继承和多态性,而结构则更适合表示轻量级数据和值类型,以提高性能并避免引用的管理开销。

类和结构有以下几个基本的不同点:

值类型 vs 引用类型:

  • 结构是值类型(Value Type): 结构是值类型,它们在栈上分配内存,而不是在堆上。当将结构实例传递给方法或赋值给另一个变量时,将复制整个结构的内容。
  • 类是引用类型(Reference Type): 类是引用类型,它们在堆上分配内存。当将类实例传递给方法或赋值给另一个变量时,实际上是传递引用(内存地址)而不是整个对象的副本。

继承和多态性:

  • 结构不能继承: 结构不能继承其他结构或类,也不能作为其他结构或类的基类。
  • 类支持继承: 类支持继承和多态性,可以通过派生新类来扩展现有类的功能。

默认构造函数:

  • 结构不能有无参数的构造函数: 结构不能包含无参数的构造函数(不带传参的)。每个结构都必须有至少一个有参数的构造函数(有传参的)。
  • 类可以有无参数的构造函数: 类可以包含无参数的构造函数(不带传参的),如果没有提供构造函数,系统会提供默认的无参数构造函数。

名词解释:构造函数(Constructor)是一种特殊的方法,主要用于在创建对象时初始化对象(构造函数的主要目的是在对象被创建时设置对象的初始状态或初始值。)。

赋值行为:

  • 类型为类的变量在赋值时存储的是引用,因此两个变量指向同一个对象。
  • 结构变量在赋值时会复制整个结构,因此每个变量都有自己的独立副本。

传递方式:

  • 类型为类的对象在方法调用时通过引用传递,这意味着在方法中对对象所做的更改会影响到原始对象。
  • 结构对象通常通过值传递,这意味着传递的是结构的副本,而不是原始结构对象本身。因此,在方法中对结构所做的更改不会影响到原始对象。

可空性:

  • **结构体是值类型,不能直接设置为 null:**因为 null 是引用类型的默认值,而不是值类型的默认值。如果你需要表示结构体变量的缺失或无效状态,可以使用 Nullable<T> 或称为 T? 的可空类型。

  • 类默认可为null: 类的实例默认可以为 null,因为它们是引用类型。

  • 性能和内存分配:

  • 结构通常更轻量: 由于结构是值类型且在栈上分配内存,它们通常比类更轻量,适用于简单的数据表示。

  • 类可能有更多开销: 由于类是引用类型,可能涉及更多的内存开销和管理。

cs 复制代码
using System;
using System.Text;

struct Books
{
    private string title;
    private string author;
    private string subject;
    private int book_id;
    public void setValues(string t, string a, string s, int id)
    {
        title = t;
        author = a; 
        subject = s;
        book_id = id;
    }
    public void display()
    {
        Console.WriteLine("Title : {0}", title);
        Console.WriteLine("Author : {0}", author);
        Console.WriteLine("Subject : {0}", subject);
        Console.WriteLine("Book_id :{0}", book_id);
    }
};
public class testStructure
{
    public static void Main(string[] args)
    {
        Books Book1 = new Books(); /* 声明 Book1,类型为 Books */
        Books Book2 = new Books(); /* 声明 Book2,类型为 Books */
        /* book 1 方法调用 */
        Book1.setValues("C Programming",
        "Nuha Ali", "C Programming Tutorial", 6495407);

        /* book 2 方法调用 */
        Book2.setValues("Telecom Billing",
        "Zara Ali", "Telecom Billing Tutorial", 6495700);
        /* 打印 Book1 信息 */
        Book1.display();

        /* 打印 Book2 信息 */
        Book2.display();

        Console.ReadKey();
    }

}
相关推荐
开心工作室_kaic41 分钟前
基于Vue的兴趣活动推荐APP的设计与实现_kaic
java·c语言·开发语言·数据库·python·sqlite·php
完球了43 分钟前
【Day14-单例设计模式&动态代理】
java·开发语言·笔记·学习·设计模式·学习经验
.昭阳.44 分钟前
小程序——生命周期
java·开发语言·前端·小程序
Ajiang28247353044 小时前
贪吃蛇项目实现(C语言)——附源码
c语言·开发语言
guicai_guojia4 小时前
面试题篇: 跨域问题如何处理(Java和Nginx处理方式)
java·开发语言·nginx
鼠鼠龙年发大财5 小时前
fly专享
开发语言·php
hunandede5 小时前
直播相关02-录制麦克风声音,QT 信号与槽,自定义信号和槽
开发语言·qt
lzb_kkk5 小时前
【Redis】redis5种数据类型(哈希)
开发语言·redis·算法·缓存·哈希算法
Good_tea_h6 小时前
如何实现Java中的多态性
java·开发语言·python
格林威7 小时前
Baumer工业相机堡盟工业相机如何通过BGAPISDK使用短曝光功能(曝光可设置1微秒)(C语言)
c语言·开发语言·人工智能·数码相机·计算机视觉