Добавление элементов в список <T>с использованием отражения - PullRequest
12 голосов
/ 16 ноября 2010

Я пытался добавить элементы в IList с помощью отражения, но при вызове метода «Add» была выдана ошибка «объект ref. Not set». Во время отладки я узнал, что GetMethod («Добавить») возвращает нулевую ссылку.

Type objTyp = typeof(MyObject); //HardCoded TypeName for demo purpose
var IListRef = typeof (List<>);
Type[] IListParam = {objTyp};          
object Result = IListRef.MakeGenericType(IListParam);

MyObject objTemp = new MyObject(); 
Result.GetType().GetMethod("Add").Invoke(Result, new[] {objTemp });

Пожалуйста, помогите.

Ответы [ 3 ]

30 голосов
/ 16 ноября 2010

Вы пытаетесь найти метод Add в Type, а не в List<MyObject> - и затем вы пытаетесь вызвать его на Type.

MakeGenericType возвращает тип, а не экземпляр этого типа.Если вы хотите создать экземпляр, обычно лучше использовать Activator.CreateInstance.Попробуйте это:

Type objTyp = typeof(MyObject); //HardCoded TypeName for demo purpose
var IListRef = typeof (List<>);
Type[] IListParam = {objTyp};          
object Result = Activator.CreateInstance(IListRef.MakeGenericType(IListParam));

MyObject objTemp = new MyObject(); 
Result.GetType().GetMethod("Add").Invoke(Result, new[] {objTemp });

(Я бы также посоветовал вам начать следовать соглашениям для имен переменных, но это отдельный вопрос.)

3 голосов
/ 16 сентября 2013
    private static void Test()
    {
        IList<Guid> list = CreateList<Guid>();
        Guid objTemp = Guid.NewGuid();
        list.Add(objTemp);
    }

    private static List<TItem> CreateList<TItem>()
    {
        Type listType = GetGenericListType<TItem>();
        List<TItem> list = (List<TItem>)Activator.CreateInstance(listType);
        return list;
    }

    private static Type GetGenericListType<TItem>()
    {
        Type objTyp = typeof(TItem);
        var defaultListType = typeof(List<>);
        Type[] itemTypes = { objTyp };
        Type listType = defaultListType.MakeGenericType(itemTypes);
        return listType;
    }

IList.Add (объект item); => вы можете использовать метод Add в интерфейсе IList вместо Reflection.

0 голосов
/ 16 ноября 2010

Вы создали только универсальный тип, но не создали экземпляр этого типа. У вас есть тип списка, но у вас нет списка.

Переменная Result содержит объект Type, поэтому Result.Gettype() возвращает то же самое, что и typeof(Type). Вы пытаетесь найти метод Add в классе Type, а не в своем списке.

Не могли бы вы использовать дженерики вместо рефлексии, например ::

public static List<T> CreateListAndAddEmpty<T>() where T : new() {
  List<T> list = new List<T>();
  list.Add(new T());
  return list;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...