索引器是一种特殊的属性,允许类或结构的实例像数组一样通过索引进行访问。它提供了使用 [] 运算符访问对象中元素集合的便捷方式。
一、考察索引器的定义与使用 难度:⭐
定义一个 StudentClass 班级类,该类中包含一个集合 用于存储学生姓名。要求实现索引器 ,使得可以通过学号(从1开始编号)来访问和修改对应的学生姓名。
具体要求
-
类的成员:
-
一个私有集合(可以使用
List<string>或ArrayList)存储学生姓名 -
一个私有字段
classSize记录班级人数
-
-
构造函数:
-
接受一个整数参数
size,表示班级人数 -
初始化集合,并将所有学生姓名初始化为空字符串
""或"未分配"
-
-
索引器:
-
参数为
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 对象。要求为该集合定义两个重载的索引器:
-
根据 Id(整数)查找:返回对应学生的地址
-
根据 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["李四"]}");
}
}
思考:索引器中的索引在集合中是重复的会怎样,比如根据学生姓名找学生地址,如果集合中有两个学生的姓名是相同的呢?