Adding items to List using reflection

2020-02-08 06:45发布

问题:

I was trying to add items to IList through reflection, but while calling the "Add" method an error was thrown "object ref. not set". While debugging I came to know that the GetMethod("Add") was returning a NULL reference.

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 });

Please help.

回答1:

You're trying to find an Add method in Type, not in List<MyObject> - and then you're trying to invoke it on a Type.

MakeGenericType returns a type, not an instance of that type. If you want to create an instance, Activator.CreateInstance is usually the way to go. Try this:

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 });

(I would also suggest that you start following conventions for variable names, but that's a separate matter.)



回答2:

    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(object item); => you can use Add method in IList interface instead of Reflection.



回答3:

You have only created a generic type, you haven't created an instance of the type. You have a list type, but you don't have a list.

The Result variabled contains a Type object, so Result.Gettype() returns the same as typeof(Type). You are trying to find an Add method in the Type class, not your list class.

Could you not use generics instead of reflection, e.g.:

public static List<T> CreateListAndAddEmpty<T>() where T : new() {
  List<T> list = new List<T>();
  list.Add(new T());
  return list;
}


标签: c# reflection