c#笔记之泛型和结构体、枚举


学习内容:

泛型用 <T> 表示,T 是类型参数 (Type Parameter),可以理解成类型占位符。一般是T开头或者直接T,只要有这个标志就是泛型,常见的List<int>这个就是泛型;类型参数是int

cs 复制代码
class Test<T>//泛型类
{

}

public void TestRun<T>(T value)//泛型方法
{

}

一、作用(以及泛型类的声明)

有一个水果店,卖苹果买一个苹果用一个盒子包起来

cs 复制代码
 internal class Program
 {
     static async Task Main(string[] args)
     {
         Apple a = new Apple() { Color = "Red" };
         Box b = new Box() { Cargo = a };
   Console.WriteLine(b.Cargo.Color);
     }
 }
 class Apple
 {
     public string Color { get; set; }

 }
 class Box
 {
     public Apple Cargo { get; set; }
 }

如果这时候要买书的话就要重写建一个装书的box类

cs 复制代码
class Book
{
}
 class BookBox
 {
     public Book Cargo { get; set; }
 }

这样会很麻烦这时候就可以用泛型,

cs 复制代码
 internal class Program
 {
     static async Task Main(string[] args)
     {
         Apple a = new Apple() { Color = "Red" };
         Book bk = new Book() { Name = "xxx"};
         Box<Apple> b = new Box<Apple>() { Cargo = a };
         Box<Book> b1 = new Box<Book>() {Cargo = bk};
         Console.WriteLine(b.Cargo.Color);
         Console.WriteLine(b1.Cargo.Name);
     }
 }
 class Apple
 {
     public string Color { get; set; }

 }
  class Book
 {
     public string  Name { get; set; }

 }
 class Box<T> //使用了泛型 
 {
     public T Cargo { get; set; }
 }
////////////////
也可以 
 class Box<TCargo > //只要对的上
 {
     public TCargo  Cargo { get; set; }
 }

就可以知道泛型 = 通用的类型 + 通用的代码 它允许你写一套代码,适配任意类型(int、string、自定义类...),不用重复写多套逻辑。

二、泛型方法

在方法名字后面加<T> 这个方法就是泛型方法,下面例子就是交换两个相同类型的值;

cs 复制代码
static void Swap<T>(ref T lhs, ref T rhs)//方法要两个T类型的参数
        {
            T temp; //声明一个T类型的参数temp
            temp = lhs;
            lhs = rhs;
            rhs = temp;
        }
比如
Swap(ref 1,ref 2);

这时候系统判断T是int类型,方法里的Temp就是int类型的

Swap(ref "s",ref "f");

这时候系统判断T是string类型,方法里的Temp就是string类型的

或者 用上一个例子的Apple类型也可以()
 Apple a = new Apple() { Color = "Red" };
 Apple a1 = new Apple() { Color = "Red1" };
Swap(ref a,ref a1);
这时候系统判断T是Apple类型,方法里的Temp就是Apple类型的,a的Color的值就是Read1了

三、泛型接口

有一个接口有个ID属性将来会有很多类型,所以使用了泛型;Student类来实现这个接口有两种形式;类也不管ID类型继续泛型下去;或者类明确id类型

cs 复制代码
 internal class Program
 {
     static async Task Main(string[] args)
     {
           Student student = new Student() { ID =1,Name = "xm"};

      /////////////////////////////
      Student<string> student1 = new Student<string>() { ID = "一",Name = "xh"};
      Student<int> student2 = new Student<int>() { ID = 25, Name = "xh" };
       
     }  
 }
 interface IUnique<T>
 {
     public T ID {  get; set; }
 }

 public class Student<T>:IUnique<T>//类也还是不知道id类型所以还是泛型
 {
     public string Name { get; set; }
     public T ID { get; set; }
 }

 public class Student1 : IUnique<int>//类知道id类型是int
 {
     public string Name { get; set; }
     public int ID { get; set; }
 }

四、泛型约束

用于限制 T 能是什么类型,格式是where T : ...

4.1接口约束

cs 复制代码
interface IAnimal
{
    void Speak();
}

class Dog : IAnimal
{
    public void Speak() => Console.WriteLine("汪汪");
}

// 约束 T 必须实现 IAnimal接口
void Test<T>(T animal) where T : IAnimal
{
    animal.Speak(); // 有约束才能调用,否则编译器报错
}

常见约束

where T : struct // 必须是值类型(int、bool、DateTime 等)

where T : class // 必须是引用类型(类、接口、委托、数组)

where T : new() // 必须有无参构造函数

where T : 基类名 // 必须是该基类或其子类

where T : 接口名 // 必须实现该接口

where T : U // T 必须是 U 或 U 的子类

五、枚举(enum)

5.1.是什么?

枚举是一组命名的整型常量 ,专门用来表示固定不变的选项 / 状态,让代码更易读、更安全。常用结构如下

cs 复制代码
// 定义枚举
enum 枚举名
{
    常量1,
    常量2,
    常量3
}

常见例子:不定义的话从0开始,后面的加一

cs 复制代码
// 定义:表示游戏角色状态
enum PlayerState
{
    Idle,    // 0(默认从0开始)
    Run,     // 1
    Attack,  // 2
    Die      // 3
}

// 使用
class Program
{
    static void Main()
    {
        // 声明枚举变量
        PlayerState state = PlayerState.Run;

        // 枚举转整数
        int stateNum = (int)state; // 结果:1

        // 整数转枚举
        PlayerState state2 = (PlayerState)2; // Attack

        Console.WriteLine(state); // 输出:Run
    }
}

5.2常见特性

5.2.1.可以自己定义数字

cs 复制代码
enum Gender
{
    Male = 1,
    Female = 2,
    Unknown = 99
}

而且如果只定义一个的话系统会自己加一

cs 复制代码
enum Gender
{
    Male ,
    Female = 4,
    Unknown 
}

这种情况的话Male因为没有定义而且是第一个所以默认是0,Unknown =5因为定义了上一个所以默认加一得到5

5.2.2Flags 特性(允许组合多个值)

cs 复制代码
[Flags] // 关键特性
enum Permission
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4
}

// 使用:同时拥有读和写权限
Permission p = Permission.Read | Permission.Write;

六、结构体(struct)

6.1. 是什么?

struct 是值类型 ,轻量、高效,适合封装少量简单数据(比如坐标、颜色、尺寸).类在内存上太大所以发明了结构体

6.2. 核心特点

  • 值类型:赋值时会拷贝一份完整数据,不是引用
  • 栈上分配(小型结构体),性能比类更好
  • 不能继承,也不能被继承
  • 可以有字段、方法、构造函数、属性

基本格式:

cs 复制代码
struct 结构体名
{
    // 字段/属性/方法
}

6.3 例子

cs 复制代码
// 定义:坐标结构体
struct Point
{
    // 字段
    public int X;
    public int Y;

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

    // 方法
    public void Print()
    {
        Console.WriteLine($"X:{X}, Y:{Y}");
    }
}

// 使用
class Program
{
    static void Main()
    {
        // 创建结构体实例
        Point p1 = new Point(10, 20);
        p1.Print(); // X:10, Y:20

        // 值类型特性:赋值是拷贝,互不影响
        Point p2 = p1;
        p2.X = 100;
        Console.WriteLine(p1.X); // 10(没变)
    }
}

6.4和类的对比

特性 结构体(struct) 类(class)
类型 值类型 引用类型
内存 栈(小型)/ 托管堆 托管堆
继承 不支持继承 支持继承
性能 高(轻量) 相对较低
用途 小型数据(坐标、颜色) 复杂对象(人、订单、车)

学习时间:

26.03.31

相关推荐
墨^O^2 小时前
进程与线程的核心区别及 Linux 启动全过程解析
linux·c++·笔记·学习
寒秋花开曾相惜2 小时前
(学习笔记)3.9 异质的数据结构(3.9.1 结构)
c语言·网络·数据结构·数据库·笔记·学习
猹叉叉(学习版)3 小时前
【系统分析师_知识点整理】 10.软件需求工程
笔记·需求分析·软考·系统分析师
LuminousCPP3 小时前
C语言自定义类型全解析
c语言·笔记·枚举·结构体·联合体
深蓝海拓3 小时前
西门子S7-1500PLC的常用Area地址以及网络读写
笔记·学习·plc
一轮弯弯的明月4 小时前
博弈论-Nim游戏
笔记·蓝桥杯·学习心得
Hello_Embed4 小时前
嵌入式上位机开发入门(五):UDP 编程 —— Server 端实现
笔记·单片机·网络协议·udp·嵌入式
热水过敏4 小时前
前路迷茫,再次起航
笔记·程序人生·职场和发展
chase。4 小时前
【学习笔记】RoboForge:让文本指令“落地”到人形机器人——一个物理优化与隐式驱动的端到端框架
笔记·学习·机器人