C#索引器练习题

索引器是一种特殊的属性,允许类或结构的实例像数组一样通过索引进行访问。它提供了使用 [] 运算符访问对象中元素集合的便捷方式。

一、考察索引器的定义与使用 难度:⭐

定义一个 StudentClass 班级类,该类中包含一个集合 用于存储学生姓名。要求实现索引器 ,使得可以通过学号(从1开始编号)来访问和修改对应的学生姓名。

具体要求

  1. 类的成员:

    • 一个私有集合(可以使用 List<string> 或 ArrayList)存储学生姓名

    • 一个私有字段 classSize 记录班级人数

  2. 构造函数:

    • 接受一个整数参数 size,表示班级人数

    • 初始化集合,并将所有学生姓名初始化为空字符串 "" 或 "未分配"

  3. 索引器:

    • 参数为 int studentId(学号,从1开始)

    • get:返回指定学号的学生姓名,如果学号无效则返回 "学号无效"

    • set:设置指定学号的学生姓名,如果学号无效则不进行任何操作(或抛出异常)

cs 复制代码
using System;
using System.Collections.Generic;

public class StudentClass
{
    private List<string> students;  // 存储学生姓名的集合
    private int classSize;           // 班级人数
    
    // 构造函数
    public StudentClass(int size)
    {
        if (size <= 0)
            throw new ArgumentException("班级人数必须大于0");
            
        classSize = size;
        students = new List<string>(size);
        
        // 初始化集合,填充空字符串
        for (int i = 0; i < size; i++)
        {
            students.Add("未分配");
        }
    }
    
    // 索引器
    public string this[int studentId]
    {
        get
        {
            // 检查学号是否有效(1 到 classSize)
            if (studentId >= 1 && studentId <= classSize)
            {
                return students[studentId - 1];  // 转换为0基索引
            }
            return "学号无效";
        }
        set
        {
            // 检查学号是否有效
            if (studentId >= 1 && studentId <= classSize)
            {
                students[studentId - 1] = value;
            }
            else
            {
                Console.WriteLine($"错误:学号 {studentId} 无效,有效范围为 1-{classSize}");
            }
        }
    }
    
   
}

// 测试代码
class Program
{
    static void Main()
    {
        // 创建有5个学生的班级
        StudentClass myClass = new StudentClass(5);
        
        // 通过索引器设置学生姓名
        myClass[1] = "张三";
        myClass[2] = "李四";
        myClass[3] = "王五";
        
        // 通过索引器获取学生姓名
        Console.WriteLine($"学号1: {myClass[1]}");
        Console.WriteLine($"学号3: {myClass[3]}");
        Console.WriteLine($"学号5: {myClass[5]}");  // 未分配
        Console.WriteLine($"学号6: {myClass[6]}");  // 无效学号
        
        // 修改学生姓名
        myClass[2] = "李小四";
        Console.WriteLine($"学号2: {myClass[2]}");
        
      
    }
}

二、考察索引器的重载 难度⭐⭐

定义一个 Student 类,包含三个属性:Id(学号)、Name(姓名)、Address(地址)。

再定义一个 StudentManager 类,该类内部使用集合 (如 List<Student> 或 Dictionary)存储多个 Student 对象。要求为该集合定义两个重载的索引器:

  1. 根据 Id(整数)查找:返回对应学生的地址

  2. 根据 Name(字符串)查找:返回对应学生的地址

具体要求

1. Student 类

  • 属性:int Id、string Name、string Address

  • 构造函数:初始化三个属性

  • 可选:重写 ToString() 方法方便输出

2. StudentManager 类

  • 私有集合:存储 Student 对象(使用 List<Student> 或 Dictionary<int, Student>)

  • 索引器1 :参数为 int id,返回该学生的地址(string 类型)

    • 如果找到返回地址

    • 如果未找到返回 "未找到该学号的学生"

  • 索引器2 :参数为 string name,返回该学生的地址(string 类型)

    • 如果找到返回地址

    • 如果未找到返回 "未找到该姓名的学生"

    • 注意:如果有重名学生,返回第一个匹配的学生的地址

3. 额外要求

  • 提供 AddStudent(Student student) 方法添加学生

  • 提供 RemoveStudent(int id) 方法删除学生(可选)

  • 提供 DisplayAllStudents() 显示所有学生信息(可选)

基础要求的测试代码:

cs 复制代码
// 创建学生对象
Student s1 = new Student(1001, "张三", "北京市朝阳区");
Student s2 = new Student(1002, "李四", "上海市浦东新区");
Student s3 = new Student(1003, "王五", "广州市天河区");
Student s4 = new Student(1004, "张三", "深圳市南山区"); // 重名学生

// 创建管理器并添加学生
StudentManager manager = new StudentManager();
manager.AddStudent(s1);
manager.AddStudent(s2);
manager.AddStudent(s3);
manager.AddStudent(s4);

// 使用 Id 索引器查找地址
Console.WriteLine($"学号1001的学生地址:{manager[1001]}");
Console.WriteLine($"学号1002的学生地址:{manager[1002]}");
Console.WriteLine($"学号9999的学生地址:{manager[9999]}");

// 使用 Name 索引器查找地址
Console.WriteLine($"\n张三的地址:{manager["张三"]}");
Console.WriteLine($"李四的地址:{manager["李四"]}");
Console.WriteLine($"赵六的地址:{manager["赵六"]}");

// 显示所有学生
manager.DisplayAllStudents();

期望输出:

复制代码
学号1001的学生地址:北京市朝阳区
学号1002的学生地址:上海市浦东新区
学号9999的学生地址:未找到该学号的学生

张三的地址:北京市朝阳区
李四的地址:上海市浦东新区
赵六的地址:未找到该姓名的学生

所有学生信息:
学号:1001, 姓名:张三, 地址:北京市朝阳区
学号:1002, 姓名:李四, 地址:上海市浦东新区
学号:1003, 姓名:王五, 地址:广州市天河区
学号:1004, 姓名:张三, 地址:深圳市南山区

完整参考代码:

cs 复制代码
using System;
using System.Collections.Generic;

// 1. Student 类
class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    
    public Student(int id, string name, string address)
    {
        Id = id;
        Name = name;
        Address = address;
    }
    
    public override string ToString()
    {
        return $"学号:{Id}, 姓名:{Name}, 地址:{Address}";
    }
}

// 2. StudentManager 类
class StudentManager
{
    private List<Student> students;  // 使用 List 存储
    
    public StudentManager()
    {
        students = new List<Student>();
    }
    
    // 添加学生
    public void AddStudent(Student student)
    {
        students.Add(student);
        Console.WriteLine($"已添加学生:{student.Name} (学号:{student.Id})");
    }
    
    // 索引器1 - 根据 Id 查找地址
    public string this[int id]
    {
        get
        {
            // 方法1:使用 foreach 遍历
            foreach (Student stu in students)
            {
                if (stu.Id == id)
                {
                    return stu.Address;
                }
            }
            return "未找到该学号的学生";
            
            /* 方法2:使用 Find 方法
            Student found = students.Find(s => s.Id == id);
            return found != null ? found.Address : "未找到该学号的学生";
            */
        }
    }
    
    // 索引器2 - 根据 Name 查找地址
    public string this[string name]
    {
        get
        {
            // 查找第一个匹配的学生
            foreach (Student stu in students)
            {
                if (stu.Name == name)
                {
                    return stu.Address;
                }
            }
            return "未找到该姓名的学生";
            
            /* 方法2:使用 Find 方法
            Student found = students.Find(s => s.Name == name);
            return found != null ? found.Address : "未找到该姓名的学生";
            */
        }
    }
    
    // 删除学生(可选)
    public bool RemoveStudent(int id)
    {
        Student student = students.Find(s => s.Id == id);
        if (student != null)
        {
            students.Remove(student);
            Console.WriteLine($"已删除学生:{student.Name} (学号:{id})");
            return true;
        }
        Console.WriteLine($"未找到学号为 {id} 的学生,删除失败");
        return false;
    }
    
    // 显示所有学生
    public void DisplayAllStudents()
    {
        if (students.Count == 0)
        {
            Console.WriteLine("暂无学生信息");
            return;
        }
        
        Console.WriteLine("\n所有学生信息:");
        foreach (Student stu in students)
        {
            Console.WriteLine(stu);
        }
        Console.WriteLine();
    }
}

// 3. 测试代码
class Program
{
    static void Main()
    {
        // 创建学生对象
        Student s1 = new Student(1001, "张三", "北京市朝阳区");
        Student s2 = new Student(1002, "李四", "上海市浦东新区");
        Student s3 = new Student(1003, "王五", "广州市天河区");
        Student s4 = new Student(1004, "张三", "深圳市南山区"); // 重名
        
        // 创建管理器并添加学生
        StudentManager manager = new StudentManager();
        manager.AddStudent(s1);
        manager.AddStudent(s2);
        manager.AddStudent(s3);
        manager.AddStudent(s4);
        
        Console.WriteLine("\n========== 测试 Id 索引器 ==========");
        // 使用 Id 索引器查找地址
        Console.WriteLine($"学号1001的学生地址:{manager[1001]}");
        Console.WriteLine($"学号1002的学生地址:{manager[1002]}");
        Console.WriteLine($"学号1003的学生地址:{manager[1003]}");
        Console.WriteLine($"学号1004的学生地址:{manager[1004]}");
        Console.WriteLine($"学号9999的学生地址:{manager[9999]}");
        
        Console.WriteLine("\n========== 测试 Name 索引器 ==========");
        // 使用 Name 索引器查找地址
        Console.WriteLine($"张三的地址:{manager["张三"]}");
        Console.WriteLine($"李四的地址:{manager["李四"]}");
        Console.WriteLine($"王五的地址:{manager["王五"]}");
        Console.WriteLine($"赵六的地址:{manager["赵六"]}");
        
        // 显示所有学生
        manager.DisplayAllStudents();
        
        // 测试删除功能(可选)
        Console.WriteLine("\n========== 测试删除功能 ==========");
        manager.RemoveStudent(1002);
        manager.DisplayAllStudents();
        
        // 测试删除后再次查找
        Console.WriteLine($"删除后查询李四的地址:{manager["李四"]}");
    }
}

思考:索引器中的索引在集合中是重复的会怎样,比如根据学生姓名找学生地址,如果集合中有两个学生的姓名是相同的呢?

相关推荐
懂点Tech1 小时前
ctfshow MISC入门图片篇(信息附加):misc41解题思路
开发语言·python
catchadmin2 小时前
PHP 8.7 协程新提案 让跨协程代码共享请求身份
开发语言·php
念何架构之路2 小时前
go-grpc设计思想
开发语言·后端·golang
小豆庄2 小时前
视频人脸打码追踪:转场丢失、漏检和ID撞号的处理
目标检测·计算机视觉·开源·音视频·视频·python3.11
酷炫码神3 小时前
Day 10|Pinia 状态管理:把散落在各组件的数据,收进一个全局仓库
android·开发语言·javascript
工业视觉老A3 小时前
攻克牙膏朝向人工分拣痛点,AI 视觉检测保障包装工序稳定
人工智能·计算机视觉·视觉检测
Elastic 中国社区官方博客4 小时前
我们如何通过 70 多个拉取请求,将 OpenTelemetry Java agent 迁移到 invokedynamic
java·大数据·开发语言·elasticsearch·搜索引擎·全文检索·es
tyn1884 小时前
记录本地安装nacos服务的方法及异常
java·开发语言
步行cgn4 小时前
Spring MVC 视图机制的核心接口与类
java·开发语言·后端·spring·mvc
传奇开心果编程5 小时前
【Rust入门练中学】第5课:引用与借用
开发语言·rust·引用·编程语言理论·通用编程语言·借用