【C#基础知识 9】3. 数据类型 -- 3.2 引用类型

C#基础知识 3:数据类型

3.2 引用类型

引用类型 是存储在堆(heap)中的数据类型。引用类型的变量存储的是对象的引用(即内存地址),而不是对象本身。当一个引用类型变量被赋值给另一个变量时,两个变量引用同一个对象。以下是引用类型的详细讲解,包括其优点、缺点以及代码示例。

3.2.1 引用类型的基本概念

引用类型 是存储在堆中的数据类型。引用类型的变量存储的是对象的引用(内存地址),而不是对象本身。当一个引用类型变量被赋值给另一个变量时,两个变量引用同一个对象。

示例:


csharp

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

class Program
{
    static void Main(string[] args)
    {
        Person person1 = new Person();
        person1.Name = "Alice";
        person1.Age = 30;

        Person person2 = person1; // person2 引用与 person1 相同的对象
        person2.Name = "Bob";     // 修改 person2 的 Name 也会影响 person1

        Console.WriteLine($"person1.Name: {person1.Name}, person1.Age: {person1.Age}"); // 输出: person1.Name: Bob, person1.Age: 30
        Console.WriteLine($"person2.Name: {person2.Name}, person2.Age: {person2.Age}"); // 输出: person2.Name: Bob, person2.Age: 30
    }
}
3.2.2 引用类型的主要类别
  1. 类(class

    • 用户定义的复合数据类型。
    • 类可以包含字段、方法、属性、事件等。
  2. 接口(interface

    • 定义一组方法、属性、事件等的契约。
    • 类可以实现多个接口。
  3. 委托(delegate

    • 类型安全的函数指针。
    • 委托可以指向一个或多个方法。
  4. 数组(array

    • 存储相同类型的元素的集合。
    • 数组可以是一维或多维的。
  5. 字符串(string

    • 表示文本字符串。
    • 字符串是不可变的(immutable)。
  6. 枚举(enum

    • 定义一组命名的常量。
    • 枚举类型是引用类型,但编译时会被转换为整数类型。

示例:


csharp

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

public interface IPerson
{
    void Introduce();
}

public delegate void MyDelegate(string message);

public enum Day
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}
3.2.3 引用类型的优点
  1. 灵活性

    • 引用类型可以包含复杂的数据结构和行为。
    • 类可以继承和实现接口,提供多态性。
  2. 内存管理

    • 引用类型存储在堆中,适合存储大型对象。
    • 垃圾回收器自动管理堆内存,减少内存泄漏的风险。
  3. 共享对象

    • 多个引用类型变量可以引用同一个对象。
    • 适合需要共享状态的场景。
  4. 可变性

    • 引用类型是可变的,可以在运行时修改对象的状态。
    • 适合需要动态变化的对象。
  5. 多态性

    • 通过继承和接口实现多态性,提高代码的灵活性和可扩展性。
3.2.4 引用类型的缺点
  1. 性能开销

    • 引用类型存储在堆中,访问速度较慢。
    • 垃圾回收器的管理可能会带来性能开销。
  2. 内存消耗

    • 引用类型需要额外的内存来存储对象的引用。
    • 对于大量小对象,内存消耗可能较大。
  3. 空引用

    • 引用类型可以为 null,需要显式检查以避免空引用异常。
    • 增加了代码的复杂性。
  4. 复杂性

    • 引用类型的使用较为复杂,需要理解内存管理和对象生命周期。
    • 对于初学者,理解引用类型的概念和使用方法可能需要一些时间。
  5. 线程安全

    • 引用类型是可变的,多线程环境下需要额外的同步机制。
    • 增加了线程安全的复杂性。
3.2.5 引用类型的代码示例

以下是一些详细的代码示例,展示了如何声明和使用引用类型。

示例1:类

文件1:Person.cs


csharp

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

    public void Introduce()
    {
        Console.WriteLine($"Hello, my name is {Name} and I am {Age} years old.");
    }
}

文件2:Program.cs


csharp

using System;

class Program
{
    static void Main(string[] args)
    {
        Person person1 = new Person();
        person1.Name = "Alice";
        person1.Age = 30;
        person1.Introduce(); // 输出: Hello, my name is Alice and I am 30 years old.

        Person person2 = person1; // person2 引用与 person1 相同的对象
        person2.Name = "Bob";     // 修改 person2 的 Name 也会影响 person1
        person1.Introduce(); // 输出: Hello, my name is Bob and I am 30 years old.
        person2.Introduce(); // 输出: Hello, my name is Bob and I am 30 years old.
    }
}
示例2:接口

文件1:IPerson.cs


csharp

public interface IPerson
{
    void Introduce();
}

文件2:Person.cs


csharp

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

    public void Introduce()
    {
        Console.WriteLine($"Hello, my name is {Name} and I am {Age} years old.");
    }
}

文件3:Program.cs


csharp

using System;

class Program
{
    static void Main(string[] args)
    {
        IPerson person = new Person();
        person.Name = "Charlie";
        person.Age = 25;
        person.Introduce(); // 输出: Hello, my name is Charlie and I am 25 years old.
    }
}
示例3:委托

文件1:Program.cs


csharp

using System;

class Program
{
    // 定义委托
    public delegate void MyDelegate(string message);

    // 定义方法
    static void PrintMessage(string message)
    {
        Console.WriteLine(message);
    }

    static void Main(string[] args)
    {
        // 创建委托实例
        MyDelegate myDelegate = new MyDelegate(PrintMessage);

        // 调用委托
        myDelegate("Hello, World!"); // 输出: Hello, World!
    }
}
示例4:数组

文件1:Program.cs


csharp

using System;

class Program
{
    static void Main(string[] args)
    {
        // 一维数组
        int[] numbers = new int[5];
        numbers[0] = 1;
        numbers[1] = 2;
        numbers[2] = 3;
        numbers[3] = 4;
        numbers[4] = 5;

        foreach (int number in numbers)
        {
            Console.WriteLine(number); // 输出: 1 2 3 4 5
        }

        // 多维数组
        int[,] matrix = new int[2, 3];
        matrix[0, 0] = 1;
        matrix[0, 1] = 2;
        matrix[0, 2] = 3;
        matrix[1, 0] = 4;
        matrix[1, 1] = 5;
        matrix[1, 2] = 6;

        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                Console.Write(matrix[i, j] + " "); // 输出: 1 2 3 4 5 6
            }
            Console.WriteLine();
        }
    }
}
示例5:字符串

文件1:Program.cs


csharp

using System;

class Program
{
    static void Main(string[] args)
    {
        string str1 = "Hello";
        string str2 = str1; // str2 引用与 str1 相同的对象

        str2 = "World"; // 修改 str2 不会影响 str1

        Console.WriteLine($"str1: {str1}"); // 输出: str1: Hello
        Console.WriteLine($"str2: {str2}"); // 输出: str2: World

        // 字符串是不可变的
        string str3 = "Hello";
        string str4 = str3.ToUpper(); // 创建一个新的字符串对象

        Console.WriteLine($"str3: {str3}"); // 输出: str3: Hello
        Console.WriteLine($"str4: {str4}"); // 输出: str4: HELLO
    }
}
示例6:枚举

文件1:Program.cs


csharp

using System;

public enum Day
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

class Program
{
    static void Main(string[] args)
    {
        Day today = Day.Wednesday;
        Console.WriteLine($"Today is {today}"); // 输出: Today is Wednesday

        // 枚举可以转换为整数
        int dayValue = (int)today;
        Console.WriteLine($"Day value: {dayValue}"); // 输出: Day value: 3

        // 整数可以转换为枚举
        Day dayFromValue = (Day)3;
        Console.WriteLine($"Day from value: {dayFromValue}"); // 输出: Day from value: Wednesday
    }
}

通过以上详细讲解和代码示例,您可以更好地理解和使用C#中的引用类型。引用类型是存储在堆中的数据类型,提供了灵活性和多态性,但需要注意其性能开销和内存消耗。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路飞VS草帽

感谢支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值