阵列列表概念问题

本文关键字:问题 列表 阵列 | 更新日期: 2023-09-27 17:55:49

我尝试在数组列表中添加 2 种类型的对象,然后尝试显示它们,但不知何故它不起作用。我是否需要使用 2 个数组列表对象或它将如何工作?

错误信息:

无法将类型为"ArrayList_Practice.学生"的对象转换为类型 "ArrayList_Practice.员工"。

class Program
{
    static void Main(string[] args)
    {
        Student st=null;
        Employees emp = null;
        ArrayList al = new ArrayList();
        Console.WriteLine("Enter Records");
        for (int i = 0; i < 2; i++)
        {
            st = new Student();
            Console.WriteLine("Enter roll");
            st.roll = int.Parse(Console.ReadLine());
            Console.WriteLine("Enter name");
            st.name = Console.ReadLine();
            Console.WriteLine("Enter course");
            st.course = Console.ReadLine();
            al.Add(st);
            emp = new Employees();
            Console.WriteLine("Enter empID");
            emp.empID = int.Parse(Console.ReadLine());
            Console.WriteLine("Enter name");
            emp.name = Console.ReadLine();
            al.Add(emp);
        }
        Console.WriteLine("/////////////Show Records//////////");
        for (int i = 0; i < 2; i++)
        {
            Console.WriteLine("Roll "+((Student)al[i]).roll.ToString());
            Console.WriteLine("Name "+((Student)al[i]).name);
            Console.WriteLine("Course "+((Student)al[i]).course);
            Console.WriteLine("EmpID "+((Employees)al[i]).empID.ToString());
            Console.WriteLine("EmpName "+((Employees)al[i]).name);
        }
        Console.ReadKey();
    }
}
class Student
{
    public int roll{ get; set;};
    public string name{ get; set;};
    public string course{ get; set;};
}
class Employees
{
    public int empID{ get; set;};
    public string name{ get; set;};
}

}

阵列列表概念问题

你的第一个元素是一个Student,你试图在循环中的第一次迭代时将其转换为Employee。这就是您在运行时获得InvalidCastException的原因。不要使用 ArrayLists,请改用强类型的泛型集合。例如:List<T> .

如果要显示通用属性,并且希望将StudentsEmployees存储到同一列表中,则可以为它们创建通用interface并实现它。然后,您可以List<CommonInterface>并存储您的实例。但是如果你有不同的属性(似乎你有),你不能使用公共接口或基类访问它们,相反,你可以简单地创建一个扩展方法并使用Reflection来显示所有属性值,如下所示:

public static class Extensions
{
    public static string DisplayPerson<T>(this T source)
    {
        if(source == null) throw new ArgumentNullException("source");
        var flags = BindingFlags.Instance | BindingFlags.Public;
        var properties = source.GetType().GetProperties(flags);
        if (properties.Any())
        {
            StringBuilder sb = new StringBuilder();
            foreach (var prop in properties)
            {
                sb.AppendFormat("{0} : {1}", prop.Name, prop.GetValue(source));
                sb.AppendLine();
            }
            return sb.ToString();
        }
        return string.Empty;
    }
}

然后只需从循环中调用它:

for (int i = 0; i < al.Count; i++)
{
    Console.WriteLine(al[i].DisplayPerson());
}

编辑:使用通用界面的另一种方式

public interface IPerson
{
    string Name { get; set; }
    int Id { get; set; }
}
class Student : IPerson
{
   /* implement the properties */
}
class Employees : IPerson
{
    /* implement the properties */
}
static void Main(string[] args)
{
    List<IPerson> personList = new List<IPerson>();
    personList.Add(new Student {/* set properties */});
    personList.Add(new Employee {/* set properties */});
    //  use a loop and display your properties without casting
}

在数组列表中,第 0 个元素是学生类型,第一个元素是员工类型。

在循环中,然后您尝试将第 0 个元素强制转换为员工以显示 empID。因此,您需要注意这一点。

您需要进行适当的投射检查才能使循环正常工作。检查元素是学生还是员工并相应地显示。

for (int i = 0; i < al.Count; i++)
{
 var student = al[i] as Student;
 if (student != null)
 {
        Console.WriteLine("Roll "+ student.roll.ToString());
        Console.WriteLine("Name "+ student.name);
        Console.WriteLine("Course "+ student.course);
 }
 else
 {
  var employee  = al[i] as Employee;
  if (employee  != null)
  {
        Console.WriteLine("EmpID "+ employee.empID.ToString());
        Console.WriteLine("EmpName "+ employee.name);
  }
 }
}

虽然这适用于您的问题,但通常您应该使用强类型集合。例如 List<Student>List<Employee>

您需要两个列表,因为您尝试在数组中存储两种不同类型的对象。虽然可以管理它,但你最好保持简单:为学生提供一个数组,为员工提供一个数组。

我不确定您为什么同时成对输入学生和员工记录。员工是否以某种方式与学生有联系?学生是员工吗?如果是这样,您最好创建一个表示学生-员工或任何关系的对象,并用该类型的项目填充单个列表。

另外,现在是 2014 年,您不应该使用 ArrayList .至少,使用 List<> .