我已经彻底阅读了这个问题的半答案,以及MSDN关于泛型类的所有内容,但是当泛型类继承自另一个类时我仍然遇到麻烦:where T: ClassName
例如,这是我的通用列表类
public class MyGenericList2<T> where T : Person
{
private T[] list;
public MyGenericList2(int size)
{
list = new T[size];
}
public T getItem(int index)
{
T temp = default(T);
temp = list[index];
return temp;
}
public void setItem(int index, T value)
{
list[index] = value;
}
public void DisplayList()
{
for (int i = 0; i < list.Length; i++)
{
Console.Out.WriteLine(list[i]);
}
}
}
它继承自person类: 注意:为了清楚起见,它缩短了
public abstract class Person
{
protected string firstName;
// Getters
public string getFirstName()
{
return this.firstName;
}
public void setFirstName(string fname)
{
this.firstName = fname;
}
}
当我尝试调用它时,我收到一个关于尝试将字符串转换为{namespace} .Person的错误,我得到的是,我试图将字符串放入“Person”框中,但是如何是否使用此机制调用该类?
这是主要方法
public static void Main(string[] args)
{
MyGenericList2<Person> studentGeneric = new MyGenericList2<Person>(3);
Student st1 = new Student();
st1.setFirstName("Thor");
studentGeneric.setItem(0, st1); //This does not work
studentGeneric.setItem(1, Person.setFirstName("Odin"); // Does not work
studentGeneric.setItem(2, st1.setFirstName("Slepnir"); // Does not work
studentGeneric.DisplayList();
Console.ReadLine();
}
如果我删除Where T : Person
并使用GenericList2<string>
它可以正常工作,这是有道理的,因为它是字符串到字符串。
任何帮助将不胜感激
快速澄清学生继承自人:
public class Student : Person
{
// Student 1
private string studentID01 = "001";
public string getStudentID01()
{
return this.studentID01;
}
}
答案 0 :(得分:1)
您错误地使用了setItem
。此方法可用于在list
类的实例中设置MyGenericList2
数组中元素的值。
要在Student类的实例上使用setFirstName
方法,请先使用getItem
返回对象实例。例如:
public void Main(string[] args)
{
MyGenericList2<Person> studentGeneric = new MyGenericList2<Person>(3);
Student st1 = new Student();
st1.setFirstName("Thor");
studentGeneric.setItem(0, st1);
Student st2 = new Student();
studentGeneric.setItem(1, st2);
studentGeneric.getItem(1).setFirstName("Odin");
Student st3 = new Student();
studentGeneric.setItem(2, st3);
studentGeneric.getItem(2).setFirstName("Slepnir");
studentGeneric.DisplayList();
Console.ReadLine();
}
要正确显示列表内容,请将您的DisplayList()
方法替换为:
public void DisplayList()
{
for (int i = 0; i < list.Length; i++)
{
if(list[i] != null){
Console.Out.WriteLine("{0}: {1}", i, list[i].getFirstName());
}
else
{
Console.Out.WriteLine("{0}: [NULL]", i);
}
}
}
答案 1 :(得分:1)
首先,我建议您为类使用公共属性,例如:
public abstract class Person
{
public string FirstName { get; set; }
}
public class Student : Person
{
public string StudentId { get; set; }
}
这意味着您的列表代码将如下所示:
Student st1 = new Student();
st1.FirstName = "Thor";
studentGeneric.setItem(0, st1);
你甚至可以使用这种语法:
studentGeneric.setItem(1, new Student
{
FirstName = "Odin"
});
此外,.Net Framework已经提供了一组非常好的通用集合类,您可以使用这些类,因此您不需要MyGenericList2<T>
类。例如,最常用的类是System.Collections.Generic.List
:
var people = new System.Collections.Generic.List<Person>();
people.Add(new Student
{
FirstName = "Odin"
});
甚至使用集合初始化语法:
var people = new System.Collections.Generic.List<Person>
{
new Student
{
FirstName = "Odin"
}
});
最后,将输出值输出到控制台时遇到的问题是因为C#不知道如何处理类,所以默认输出student.ToString()
的值。因为你没有告诉你的班级怎么做,它只输出类型的名称。您可以覆盖ToString
,也可以更简单地调用getFirstName()
方法:
Console.WriteLine(list[i].getFirstName());