C# 将项目添加到列表<;T>;使用反射

C# 将项目添加到列表<;T>;使用反射,c#,reflection,C#,Reflection,我试图通过反射将项目添加到IList,但在调用“add”方法时,抛出了一个错误“object ref.not set”。在调试时,我知道GetMethod(“Add”)返回了一个空引用 Type objTyp = typeof(MyObject); //HardCoded TypeName for demo purpose var IListRef = typeof (List<>); Type[] IListParam = {objTyp}; object Re

我试图通过反射将项目添加到IList,但在调用“add”方法时,抛出了一个错误“object ref.not set”。在调试时,我知道GetMethod(“Add”)返回了一个空引用

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 });
Type objTyp=typeof(MyObject)//用于演示目的的硬编码TypeName
var IListRef=类型(列表);
类型[]IListParam={objTyp};
对象结果=IListRef.MakeGenericType(IListParam);
MyObject objTemp=新的MyObject();
Result.GetType().GetMethod(“Add”).Invoke(Result,new[]{objTemp});

请提供帮助。

您试图在
类型
中找到一个
添加
方法,而不是在
列表
-然后您试图在
类型
上调用它

返回类型,而不是该类型的实例。如果你想创建一个实例,
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 });
Type objTyp=typeof(MyObject)//用于演示目的的硬编码TypeName
var IListRef=类型(列表);
类型[]IListParam={objTyp};
对象结果=Activator.CreateInstance(IListRef.MakeGenericType(IListParam));
MyObject objTemp=新的MyObject();
Result.GetType().GetMethod(“Add”).Invoke(Result,new[]{objTemp});

(我还建议您开始遵循变量名的约定,但这是另一回事。)

您只创建了泛型类型,而没有创建该类型的实例。您有列表类型,但没有列表

Result
variabled包含一个
Type
对象,因此
Result.Gettype()
返回与
typeof(Type)
相同的值。您试图在
类型
类中找到
添加
方法,而不是列表类

您能否不使用泛型而不是反射,例如:

public static List<T> CreateListAndAddEmpty<T>() where T : new() {
  List<T> list = new List<T>();
  list.Add(new T());
  return list;
}
public静态列表createListandEmpty(),其中T:new(){
列表=新列表();
添加(新的T());
退货清单;
}
专用静态无效测试()
{
IList list=CreateList();
Guid objTemp=Guid.NewGuid();
列表。添加(objTemp);
}
私有静态列表CreateList()
{
类型listType=GetGenericListType();
List=(List)Activator.CreateInstance(listType);
退货清单;
}
私有静态类型GetGenericListType()
{
类型objTyp=类型(滴度);
var defaultListType=typeof(列表);
Type[]itemTypes={objTyp};
类型listType=defaultListType.MakeGenericType(itemTypes);
返回列表类型;
}

IList.Add(对象项);=>您可以在IList接口中使用Add方法而不是Reflection。

我之前对Reflection做了很多工作,我得出结论,我不喜欢
GetMethod(string)
的重载,因为我不知道它是否会返回。尝试使用
GetMethod(string,Type[])
GetMethod(string,BindingFlags)
。也许它不起作用,也许只是我有点偏执,但我记得以前对类似的问题有过很多困惑。非常感谢,现在它起作用了。我错过了呼叫“Activator.CreateInstance”。@Jon Skeet谢谢。MakeGenericType为我节省了大量的工作。您建议的基于泛型的解决方案是一个合适的解决方案。我没有选择泛型的原因是,PropertyInfo.SetValue方法不接受泛型参数引用,否则我肯定会选择泛型版本。不起作用<代码>IList结果=(IList)IListRef.MakeGenericType(IListParam)抛出<代码>InvalidCastException无法将“System.RuntimeType”类型的对象强制转换为“System.Collections.IList”类型是的,你是对的Alex,谢谢你的警告。我忘记了创建实例。我编辑代码,在这段时间里,它已经过测试,并且正在工作;))
    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;
    }