C # Generics Typecast List <T>в список <BaseType> - PullRequest
2 голосов
/ 27 января 2011

Как я могу привести List<Car> к List<MyBaseClass>, В моем коде экземпляр List будет выглядеть как объект (требование программы не является преднамеренным), выполнив это, я получу 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; }
}

Ответы [ 7 ]

6 голосов
/ 27 января 2011

Это невозможно.

Если бы это было возможно, вы могли бы написать следующее:

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>!

Альтернативы:

  • Объявитьсписок как List<BaseCLass>
  • Приведение к неуниверсальному IList (не рекомендуется)
  • Приведение к IEnumerable<BaseClass> с использованием ковариации .Net 4
  • Передайте напечатанную копию списка:

    VehicleConverter(lstCar.ConvertAll(c => (BaseClass)c));
    
3 голосов
/ 27 января 2011

Вы не упомянули, используете ли вы .NET 4.0 или более раннюю версию, но если вы используете .NET 4.0, то вам может помочь новая функция совмещения / противоречия для общих интерфейсов.

Вы обнаружили, что вы не можете разыграть List<Car> как List<MyBaseClass>, но в .NET 4.0 вы можете разыграть IEnumerable<Car> как IEnumerable<MyBaseClass>.

Затем вы можете вызывать функции, для которых требуется IEnumerable<MyBaseClass> с вашим List<Car> в качестве параметра, без какого-либо специального преобразования или кода приведения.

Например, этот код работает в .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);
}

Надеюсь, это поможет.

1 голос
/ 27 января 2011

И причина, по которой это невозможно, заключается в том, что вы можете вызвать ошибки во время выполнения, например:

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
0 голосов
/ 27 января 2011

Несмотря на то, что я не смог преобразовать его в BaseClass, но я достиг своей цели - получить идентификатор транспортного средства с помощью 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)));
        }
    }
0 голосов
/ 27 января 2011

Это работает

if (obj is List<Car>)
{
    List<MyBaseClass> c = ((List<Car>)obj).ToList<MyBaseClass>();
}

Но вам нужно будет сделать это для каждого типа.В идеале вам следует разыграть перед передачей в VehicleConverter.

Хотя это выглядит странным требованием и предлагает вариант @ yodaj007, если вам разрешено его использовать.

0 голосов
/ 27 января 2011

Вы можете попробовать использовать метод расширения "IEnumerable.Cast ()" из пространства имен System.Linq.

Вот ссылка на документацию MSDN: http://msdn.microsoft.com/en-us/library/bb341406.aspx

Вот пример:

public void VehicleConverter(IEnumerable obj)
{
     IEnumerable<MyBaseClass> enumerable = obj.Cast<MyBaseClass>();
     List<MyBaseClass> list = enumerable.ToList();
}
0 голосов
/ 27 января 2011
public List<MyBaseClass> VehicleConverter<T>(List<T> obj)
    where T : MyBaseClass
{
    return obj.Cast<MyBaseClass>().ToList();
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...