Making a copy of a generic list to another generic list.
This seems a silly question if the type of the List is known in Advance.
Suppose I have following 3 classes –
public class A_Student
{
public int RollNo { get; set; }
public string Name { get; set; }
public string Address { get;
set; }
}
public class B_Student
{
public int RollNo { get; set; }
public string Name { get; set; }
public string Address { get;
set; }
}
public class C_Student
{
public int RollNo { get; set; }
public string FirstName { get;
set; }
public string LastName { get;
set; }
public string Address { get;
set; }
}
Now
say we created a List of A_Student as below –
List<A_Student> A_Students = new List<A_Student>()
{
new A_Student() { RollNo = 1, Name = "ABC", Address = "Bangalore "
},
new A_Student() { RollNo = 2, Name = "XYZ", Address = "Delhi "
}
};
Next
I want the same copy of A_Students
into List<B_Student>
B_Students. This is really simple question – iterate the source list and
add it to destination list as below -
public List<B_Student>
Copy(List<A_Student>
aStudents)
{
List<B_Student> bStudents = new
List<B_Student>();
foreach
(A_Student aStudent in
aStudents)
{
B_Student
bStudent = new B_Student();
bStudent.RollNo =
aStudent.RollNo;
bStudent.Name = aStudent.Name;
bStudent.Address =
aStudent.Address;
bStudents.Add(bStudent);
}
return
bStudents;
}
Now I
want the same into List<C_Student>. What you think is creation of the similar method for C_Student. What if there
are 100s of Students Type then you are going to create 100 Copy methods. This
is like programming by a Kid. What about a single method can be used for all
Such Cases. There cames Generic Method in picture.
Now the challenge comes when you want the make the above
Copy method Generic. Meaning the Type of the Source object and Destination object is not known in advance. Now several questions will come to your mind like – How can
I create the object just by knowing the type? How will I get the properties of
the Source object and set the same value
to Destination object.
Here is the solution- .NET Reflection is the hero in solving
the above mentioned problem. Find below the code.
public List<U> Copy<U,T>(List<T> sourceList)
{
Type
sourceType = typeof(T);
List<object> destinationList = new
List<object>();
var
properties = sourceType.GetProperties();
foreach
(T item in sourceList)
{
var
destinationObj = Activator.CreateInstance(typeof(U));
var
props = destinationObj.GetType().GetProperties();
foreach
(PropertyInfo pi in
props)
{
object
propValue;
try
{
propValue = (typeof(T)).GetProperty(pi.Name).GetValue(item, null);
}
catch
(Exception ex)
{
propValue = null;
}
pi.SetValue(destinationObj,
propValue,null);
}
destinationList.Add(destinationObj);
}
return
destinationList.Cast<U>().ToList() ;
}
To call
the above method simply call –
List<B_Student>
B_Students = Copy<B_Student, A_Student>(A_Students);
There
is a small catch in the above Generic Method. What if the destination object
property doesn’t match with source property. Like, C_Student Doesn’t have Name
property instead FirstName and LastName. So what we are going to get with the
following -
List<C_Student>
C_Students = Copy<C_Student, A_Student>(A_Students);
Since
the property of the Destination object doesn’t have any match in the Source type
it will remain null as below –