ArrayList概念问题

时间:2014-04-01 00:53:41

标签: c# .net arraylist console-application

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

错误讯息:

  

无法转换类型为“ArrayList_Practice.Student”的对象进行输入   'ArrayList_Practice.Employees'。

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;};
}

}

3 个答案:

答案 0 :(得分:2)

您的第一个元素是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
}

答案 1 :(得分:1)

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

在您的循环中

,然后您尝试将第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>

答案 2 :(得分:0)

您需要两个列表,因为您尝试在阵列中存储两种不同类型的对象。虽然可以对此进行管理,但最好还是保持简单:为学生准备一个阵列,为员工准备一个阵列。

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

此外,它是2014年,你不应该使用ArrayList。至少,请使用List<>