У меня есть класс с именем Animals
, который содержит два List<T>
.
Один - это список медведей, а другой - список пингвинов.
Я могу довольно просто получить список медведей, просто вызвав Bears
в переменной animals
- но как мне получить это с помощью отражения?
Я создал статический вспомогательный класс ListHelper
, с универсальным методом, который принимает Bear
или Pinguin
в качестве универсального типа, и животных в качестве аргумента, который должен возвращать список медведи, если Bear
является универсальным типом.
Этого не происходит. Вместо этого он вылетает с этим сообщением
: System.Reflection.TargetException: 'Object does not match target type
, и я не могу понять почему, потому что тип правильный, когда я проверяю его через отладчик.
Полностью «рабочий» пример ниже.
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;
class ReflectionTrouble
{
static void Main(string[] args)
{
var animals = new Animals
{
Bears = new List<Bear> {new Bear {Name = "Bear1"}, new Bear {Name = "Bear 2"}},
Pinguins = new List<Pinguin> {new Pinguin {Name = "Pingo1"}, new Pinguin {Name = "Pingo2"}}
};
var lists = ListHelper.GetList<Bear>(animals);
foreach (var bear in lists)
{
Console.WriteLine(bear.Name);
}
//expected to have printed the names of the bears here...
}
}
public static class ListHelper
{
public static IEnumerable<T> GetList<T>(Animals animals)
{
var lists = animals.GetType().GetRuntimeProperties().Where(p => p.PropertyType.IsGenericType);
foreach (var propertyInfo in lists)
{
var t = propertyInfo.PropertyType;
var typeParameters = t.GetGenericArguments();
foreach (var typeParameter in typeParameters)
{
if (typeParameter == typeof(T))
{
// This is where it crashes.
var list = (IEnumerable<T>) propertyInfo.GetValue(t);
return list;
}
}
}
return Enumerable.Empty<T>();
}
}
public class Animals
{
public IList<Bear> Bears { get; set; }
public IList<Pinguin> Pinguins { get; set; }
}
public class Bear
{
public string Name { get; set; }
}
public class Pinguin
{
public string Name { get; set; }
}