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();
    }

}
相关推荐
java1234_小锋1 分钟前
使用 RabbitMQ 有什么好处?
java·开发语言
九鼎科技-Leo7 分钟前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
wjs202410 分钟前
R 数据框
开发语言
肘击鸣的百k路15 分钟前
Java 代理模式详解
java·开发语言·代理模式
捕鲸叉25 分钟前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点41 分钟前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
真的想不出名儿44 分钟前
Java基础——反射
java·开发语言
努力编程的阿伟1 小时前
【Java SE语法】抽象类(abstract class)和接口(interface)有什么异同?
java·开发语言
包饭厅咸鱼1 小时前
QML----复制指定下标的ListModel数据
开发语言·数据库
bryant_meng1 小时前
【python】Distribution
开发语言·python·分布函数·常用分布