Reputation: 1845
How can i typecast List<Car>
to List<MyBaseClass>
, In my code instance of List will go as an object (program requirement not intentional), by doing this i will retrieve vehicleId..
public Form1()
{
List<Car> lstCar = new List<Car>();
lstCar.Add(new Car() { Make = "tootay", Model = "camry", VechicleId = 1 });
lstCar.Add(new Car() { Make = "honda", Model = "civic", VechicleId = 2 });
VehicleConverter(lstCar);
}
public void VehicleConverter(object obj)
{
//Want to typecast it to List<MyBaseClass>
}
}
public class MyBaseClass
{
public int VechicleId { get; set; }
}
public class Car:MyBaseClass
{
public string Make { get; set; }
}
public class Bike : MyBaseClass
{
public int CC { get; set; }
}
Upvotes: 2
Views: 4684
Reputation: 117175
You didn't mention if you're using .NET 4.0 or earlier, but if you are using .NET 4.0 then the new co-variance/contra-variance feature for generic interfaces may help you.
You've discovered that you can't cast List<Car>
as List<MyBaseClass>
, but with .NET 4.0 you can cast IEnumerable<Car>
as IEnumerable<MyBaseClass>
.
You could then call functions that require an IEnumerable<MyBaseClass>
with your List<Car>
as the parameter without doing any special conversion or casting code.
For example, this code works in .NET 4.0:
List<Car> lstCar = new List<Car>();
lstCar.Add(new Car() { Make = "tootay", Model = "camry", VechicleId = 1 });
lstCar.Add(new Car() { Make = "honda", Model = "civic", VechicleId = 2 });
VehicleConverter(lstCar);
public void VehicleConverter(IEnumerable<MyBaseClass> vehicles)
{
var found = vehicles.Where(v => v.VechicleId == 123);
}
I hope this helps.
Upvotes: 4
Reputation: 1845
Even though i could not convert it to BaseClass, but i achieved my objective of retrieving the vehicleId by Casting & Reflection.
public void VehicleConverter(object obj)
{
Type t = obj.GetType().GetGenericArguments()[0].GetType();
IList lstVec = ((IList)obj);
foreach (var k in lstVec)
{
PropertyInfo[] p = k.GetType().GetProperties();
foreach (PropertyInfo pi in p)
if (pi.Name == "VechicleId")
MessageBox.Show(Convert.ToString(pi.GetValue(k, null)));
}
}
Upvotes: 0
Reputation: 3340
This works
if (obj is List<Car>)
{
List<MyBaseClass> c = ((List<Car>)obj).ToList<MyBaseClass>();
}
But you would need to do it for each type. Ideally you should cast before passing to VehicleConverter.
Seems like an odd requirement though and would suggest @yodaj007 option if you are allowed to use that.
Upvotes: 0
Reputation: 575
You could try using the "IEnumerable.Cast<T>()" extension method from the System.Linq namespace.
Here is a link to the msdn documentation: http://msdn.microsoft.com/en-us/library/bb341406.aspx
Here is an example:
public void VehicleConverter(IEnumerable obj)
{
IEnumerable<MyBaseClass> enumerable = obj.Cast<MyBaseClass>();
List<MyBaseClass> list = enumerable.ToList();
}
Upvotes: 0
Reputation: 53191
And the reason why this is not possible is because you could runtime errors like this:
var cars = new List<Car>();
var vehicles = (List<MyBaseClass>)cars; // Not possible, but assume it was
vehicles.Add(new Bike()); // Runtime fail because now you are trying to add a bike to a list of cars
Upvotes: 1
Reputation:
public List<MyBaseClass> VehicleConverter<T>(List<T> obj)
where T : MyBaseClass
{
return obj.Cast<MyBaseClass>().ToList();
}
Upvotes: 0
Reputation: 888185
This is not possible.
Had it been possible, you would be able to write the following:
List<Car> carList = new List<Car>();
List<BaseClass> baseList = (List<BaseClass>)carList;
baseList.Add(new Bike()); //I just put a Bike into a List<Car>!
Alternatives:
List<BaseCLass>
IList
(not recommended)IEnumerable<BaseClass>
, using .Net 4's covariancePass a typed copy of the list:
VehicleConverter(lstCar.ConvertAll(c => (BaseClass)c));
Upvotes: 6