阵列列表概念问题
本文关键字:问题 列表 阵列 | 更新日期: 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>
.
如果要显示通用属性,并且希望将Students
和Employees
存储到同一列表中,则可以为它们创建通用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<>
.