[英]How to get a List of Base class objects, from x number of child classes lists?
為了說明,我舉了一個例子
public class Base {
public string Name { get; set; }
public string Surname { get; set; }
public Base(string name, string surname) {
Name = name;
Surname = surname;
}
}
public class Student : Base {
public int StudentID { get; set; }
public Student(string name, string surname, int studentID)
: base(name, surname) {
Name = name;
Surname = surname;
StudentID = studentID;
}
public override string ToString() {
return string.Format("Name is {0}, surname is {1}, ID is {2}",
Name, Surname, StudentID);
}
}
public class Teacher : Base {
public string TeachingSubject { get; set; }
public Teacher(string name, string surname, string teachingSubject)
: base(name, surname) {
Name = name;
Surname = surname;
TeachingSubject = teachingSubject;
}
public override string ToString() {
return string.Format("Name is {0}, surname is {1}, TeachingSubject is {2}",
Name, Surname, TeachingSubject);
}
}
在我的情況下,有4個子類,但是2個子類足以使它保持簡單並且仍然很重要。 請記住,Student和Teacher類包含它們自己的屬性,因此根據派生的類屬性,Base列表中的每個對象都應該不同。
在項目中的某個地方,我需要有一個返回基礎對象列表的方法
List<Base> GetAllLists() {
return allLists; //Lets name the return list of Base objects like this
}
因此,我需要將派生類中的對象列表放到基類列表中,並在某個地方使用它。
我已經做了這樣的事情
List<Base> GetAllLists() {
var allLists = new List<Base>();
var studentList = new StudentService().GetList(); //Service class that populates the list of students from a csv file
foreach (var item in studentList) {
allLists.Add(new Student(item.Name, item.Surname, item.StudentID));
}
var teacherList = new TeacherService().GetList(); //Service class that populates the list of teachers from a csv file
foreach (var item in teacherList) {
allLists.Add(new Teacher(item.Name, item.Surname, item.TeachingSubject));
}
return allLists;
}
我有一條評論:
無需迭代所有列表並實例化每個實體的新對象,因為它們都繼承自相同的基類
那么如何以其他方式實現這一目標呢?
var allLists = new List<Base>();
var studentList = new StudentService().GetList();
allLists.AddRange(studentList);
var teacherList = new TeacherService().GetList();
allLists.AddRange(teacherList);
由於Student
和Teacher
從基礎繼承而來的,因此他們只能適合基礎列表。
這里最大的區別是您僅添加引用! 這意味着,如果您在原始studentList
更改了一個值, studentList
它也將在allLists
列表中更改!
而在您發布的代碼中將不會發生這種情況,因為您為studentList
每個條目創建了一個新實例。 這樣,您可以在兩個列表之間創建獨立性。
但是,如果studentList
只是在其他地方未進行操作的局部變量,則可以使用AddRange
並將簡單的引用添加到allLists
列表中是合法的
這是一個小測試程序。 將其復制粘貼到控制台應用程序中,然后自己查看差異。 只需更改copyreference
值並比較結果即可:
void Main()
{
bool copyreference = true;
var allLists = new List<Base>();
var studentList = new List<Student>();
studentList.Add(new Student("Alf", "Bedrock", 123));
studentList.Add(new Student("Alfine", "Bedrock", 456));
var teacherList = new List<Teacher>();
teacherList.Add(new Teacher("Brad", "Gulp", "MATH"));
teacherList.Add(new Teacher("Evelyn", "Gulp", "BIO"));
if (copyreference)
{
allLists.AddRange(studentList);
allLists.AddRange(teacherList);
}
else
{
foreach (var item in studentList)
{
allLists.Add(new Student(item.Name, item.Surname, item.StudentID));
}
}
Console.WriteLine(String.Join(Environment.NewLine, allLists));
// TEST changing a value in the original list
studentList[0].Name = "Harry";
// if you copied references you will see the change in the final list
Console.WriteLine(Environment.NewLine + String.Join(Environment.NewLine, allLists));
}
如果允許在調用GetAllLists
方法時創建列表的新實例,我將執行以下操作
public List<Base> GetAllLists() {
var studentList = new StudentService().GetList();
var teacherList = new TeacherService().GetList();
return studentList.Cast<Base>()
.Concat(teacherList.Cast<Base>())
.ToList();
}
您不需要寫Name = name; Surname = surname;
Name = name; Surname = surname;
因為您已經擁有: base(name, surname)
關於AddRange()
的影子/深層副本,您還可以實現ICloneable
或添加副本構造函數。 例:
類的定義:
public class Base {
public string Name { get; set; }
public string Surname { get; set; }
public Base(string name, string surname) {
Name = name;
Surname = surname;
}
}
public class Student : Base, ICloneable { // ICloneable
public int StudentID { get; set; }
public Student(string name, string surname, int studentID) : base(name, surname) {
//Name = name;
//Surname = surname;
StudentID = studentID;
}
public override string ToString() {
return string.Format("Name is {0}, surname is {1}, ID is {2}", Name, Surname, StudentID);
}
public object Clone() {
return MemberwiseClone();
}
}
public class Teacher : Base { // Copy constructor
public string TeachingSubject { get; set; }
public Teacher(string name, string surname, string teachingSubject) : base(name, surname) {
//Name = name;
//Surname = surname;
TeachingSubject = teachingSubject;
}
public override string ToString() {
return string.Format("Name is {0}, surname is {1}, TeachingSubject is {2}", Name, Surname, TeachingSubject);
}
public Teacher(Teacher obj) : base(obj.Name, obj.Surname) {
TeachingSubject = obj.TeachingSubject;
}
}
用法示例:
// AddRange()
List<Student> stud = new List<Student>(2);
stud.Add(new Student("s1", "ss1", 1));
stud.Add(new Student("s2", "ss2", 2));
List<Teacher> teac = new List<Teacher>(2);
teac.Add(new Teacher("t1", "ts1", "subject1"));
teac.Add(new Teacher("t2", "ts2", "subject2"));
List<Base> bas = new List<Base>(4);
bas.AddRange(stud);
bas.AddRange(teac);
Debug.Print($"{Environment.NewLine}AddRange():");
Debug.Print($"Base List:{Environment.NewLine}{bas[0]}{Environment.NewLine}{bas[1]}{Environment.NewLine}{bas[2]}{Environment.NewLine}{bas[3]}");
stud[0] = new Student("s3_changed", "ss3_changed", 3);
stud[1].Name = "s4_changed";
stud[1].Surname = "ss4_changed";
stud[1].StudentID = 4;
bas[2].Name = "b3_changed";
bas[2].Surname = "bs3_changed";
((Teacher)bas[2]).TeachingSubject = "bsub3_changed";
bas[3] = new Teacher("t4_changed", "ts4_changed", "tsbu4_changed");
Debug.Print($"{Environment.NewLine}After Change:");
Debug.Print($"Student List:{Environment.NewLine}{stud[0]}{Environment.NewLine}{stud[1]}");
Debug.Print($"Teacher List:{Environment.NewLine}{teac[0]}{Environment.NewLine}{teac[1]}");
Debug.Print($"Base List:{Environment.NewLine}{bas[0]}{Environment.NewLine}{bas[1]}{Environment.NewLine}{bas[2]}{Environment.NewLine}{bas[3]}");
// Concat()
List<Student> stud2 = new List<Student>(2);
stud2.Add(new Student("s1", "ss1", 1));
stud2.Add(new Student("s2", "ss2", 2));
List<Teacher> teac2 = new List<Teacher>(2);
teac2.Add(new Teacher("t1", "ts1", "subject1"));
teac2.Add(new Teacher("t2", "ts2", "subject2"));
List<Base> bas2 = new List<Base>();
bas2 = bas2.Concat(stud2).Concat(teac2).ToList();
Debug.Print($"{Environment.NewLine}Concat:");
Debug.Print($"Base List:{Environment.NewLine}{bas2[0]}{Environment.NewLine}{bas2[1]}{Environment.NewLine}{bas2[2]}{Environment.NewLine}{bas2[3]}");
stud2[0] = new Student("s3_changed", "ss3_changed", 3);
stud2[1].Name = "s4_changed";
stud2[1].Surname = "ss4_changed";
stud2[1].StudentID = 4;
bas2[2].Name = "b3_changed";
bas2[2].Surname = "bs3_changed";
((Teacher)bas2[2]).TeachingSubject = "bsub3_changed";
bas2[3] = new Teacher("t4_changed", "ts4_changed", "tsbu4_changed");
Debug.Print($"{Environment.NewLine}After Change:");
Debug.Print($"Student List:{Environment.NewLine}{stud2[0]}{Environment.NewLine}{stud2[1]}");
Debug.Print($"Teacher List:{Environment.NewLine}{teac2[0]}{Environment.NewLine}{teac2[1]}");
Debug.Print($"Base List:{Environment.NewLine}{bas2[0]}{Environment.NewLine}{bas2[1]}{Environment.NewLine}{bas2[2]}{Environment.NewLine}{bas2[3]}");
// AddRange() clone
List<Student> stud3 = new List<Student>(2);
stud3.Add(new Student("s1", "ss1", 1));
stud3.Add(new Student("s2", "ss2", 2));
List<Teacher> teac3 = new List<Teacher>(2);
teac3.Add(new Teacher("t1", "ts1", "subject1"));
teac3.Add(new Teacher("t2", "ts2", "subject2"));
List<Base> bas3 = new List<Base>(4);
bas3.AddRange(stud3.Select(x => (Student)x.Clone()).ToList()); // Clone
bas3.AddRange(teac3.Select(x => new Teacher(x)).ToList()); // Copy c'tor
Debug.Print($"{Environment.NewLine}AddRange() clone:");
Debug.Print($"Base List:{Environment.NewLine}{bas3[0]}{Environment.NewLine}{bas3[1]}{Environment.NewLine}{bas3[2]}{Environment.NewLine}{bas3[3]}");
stud3[0] = new Student("s3_changed", "ss3_changed", 3);
stud3[1].Name = "s4_changed";
stud3[1].Surname = "ss4_changed";
stud3[1].StudentID = 4;
bas3[2].Name = "b3_changed";
bas3[2].Surname = "bs3_changed";
((Teacher)bas3[2]).TeachingSubject = "bsub3_changed";
bas3[3] = new Teacher("t4_changed", "ts4_changed", "tsbu4_changed");
Debug.Print($"{Environment.NewLine}After Change:");
Debug.Print($"Student List:{Environment.NewLine}{stud3[0]}{Environment.NewLine}{stud3[1]}");
Debug.Print($"Teacher List:{Environment.NewLine}{teac3[0]}{Environment.NewLine}{teac3[1]}");
Debug.Print($"Base List:{Environment.NewLine}{bas3[0]}{Environment.NewLine}{bas3[1]}{Environment.NewLine}{bas3[2]}{Environment.NewLine}{bas3[3]}");
輸出:
AddRange():
Base List:
Name is s1, surname is ss1, ID is 1
Name is s2, surname is ss2, ID is 2
Name is t1, surname is ts1, TeachingSubject is subject1
Name is t2, surname is ts2, TeachingSubject is subject2
After Change:
Student List:
Name is s3_changed, surname is ss3_changed, ID is 3
Name is s4_changed, surname is ss4_changed, ID is 4
Teacher List:
Name is b3_changed, surname is bs3_changed, TeachingSubject is bsub3_changed
Name is t2, surname is ts2, TeachingSubject is subject2
Base List:
Name is s1, surname is ss1, ID is 1
Name is s4_changed, surname is ss4_changed, ID is 4
Name is b3_changed, surname is bs3_changed, TeachingSubject is bsub3_changed
Name is t4_changed, surname is ts4_changed, TeachingSubject is tsbu4_changed
Concat:
Base List:
Name is s1, surname is ss1, ID is 1
Name is s2, surname is ss2, ID is 2
Name is t1, surname is ts1, TeachingSubject is subject1
Name is t2, surname is ts2, TeachingSubject is subject2
After Change:
Student List:
Name is s3_changed, surname is ss3_changed, ID is 3
Name is s4_changed, surname is ss4_changed, ID is 4
Teacher List:
Name is b3_changed, surname is bs3_changed, TeachingSubject is bsub3_changed
Name is t2, surname is ts2, TeachingSubject is subject2
Base List:
Name is s1, surname is ss1, ID is 1
Name is s4_changed, surname is ss4_changed, ID is 4
Name is b3_changed, surname is bs3_changed, TeachingSubject is bsub3_changed
Name is t4_changed, surname is ts4_changed, TeachingSubject is tsbu4_changed
AddRange() clone:
Base List:
Name is s1, surname is ss1, ID is 1
Name is s2, surname is ss2, ID is 2
Name is t1, surname is ts1, TeachingSubject is subject1
Name is t2, surname is ts2, TeachingSubject is subject2
After Change:
Student List:
Name is s3_changed, surname is ss3_changed, ID is 3
Name is s4_changed, surname is ss4_changed, ID is 4
Teacher List:
Name is t1, surname is ts1, TeachingSubject is subject1
Name is t2, surname is ts2, TeachingSubject is subject2
Base List:
Name is s1, surname is ss1, ID is 1
Name is s2, surname is ss2, ID is 2
Name is b3_changed, surname is bs3_changed, TeachingSubject is bsub3_changed
Name is t4_changed, surname is ts4_changed, TeachingSubject is tsbu4_changed
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.