2012-04-05 70 views
3

尝试使用反射将类对象添加到列表中,但是当使用我的类对象作为参数调用Add方法时,我得到'对象与目标类型不匹配'C#反射列表:对象与目标类型不匹配

这里是在关注的代码段(你可以假设classString = "Processor"现在)

PC fetched = new PC(); 

// Get the appropriate computer field to write to 
FieldInfo field = fetched.GetType().GetField(classString); 

// Prepare a container by making a new instance of the reffered class 
// "CoreView" is the namespace of the program. 
object classContainer = Activator.CreateInstance(Type.GetType("CoreView." + classString)); 

/* 
    classContainer population code 
*/ 

// This is where I get the error. I know that classContainer is definitely 
// the correct type for the list it's being added to at this point. 
field.FieldType.GetMethod("Add").Invoke(fetched, new[] {classContainer}); 

那么这就是上面的代码添加到classContainers类的一部分:

public class PC 
{ 
    public List<Processor> Processor = new List<Processor>(); 
    public List<Motherboard> Motherboard = new List<Motherboard>(); 
    // Etc... 
} 

回答

4

你试图调用List.Add(Processor)PC - 你要调用它在球场上的值:

field.FieldType.GetMethod("Add").Invoke(field.GetValue(fetched), 
             new[] {classContainer}); 

不过,我个人建议你有这样的公共领域。考虑使用属性。

+0

这奏效了!每次我揭露一个公共领域,有人抱怨= P,这真是太神奇了。别担心,一旦我接近发布该程序,它们将成为物业。我仍然不完全明白为什么他们应该是属性。 – CJxD 2012-04-05 17:59:49

+1

@CJxD:有关参数,请参阅http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx。你可能甚至不想直接将它们公开为列表 - 你可能想要公开某些操作,比如“AddProcessor”,“AddMotherboard”等。这取决于你想要达到什么级别的封装。 – 2012-04-05 18:01:00

+0

获取代码分析工具并将其打开您的代码。它会痛苦地嚎叫。从与类型名称相同的成员,不使用属性,暴露具体类型...你不用这种快捷方式自己做任何事情。公开列表处理器{get;设置;}(或更好的私人设置),几乎不是一个巨大的不合理的负担。 – 2012-04-05 21:41:40

0

此方法将新项目添加到列表中的所有//只是代替插入使用添加

 IList list = (IList)value;// this what you need to do convert ur parameter value to ilist 

     if (value == null) 
     { 
      return;//or throw an excpetion 
     } 

     Type magicType = value.GetType().GetGenericArguments()[0];//Get class type of list 
     ConstructorInfo magicConstructor = magicType.GetConstructor(Type.EmptyTypes);//Get constructor reference 

     if (magicConstructor == null) 
     { 
      throw new InvalidOperationException(string.Format("Object {0} does not have a default constructor defined", magicType.Name.ToString())); 
     } 

     object magicClassObject = magicConstructor.Invoke(new object[] { });//Create new instance 
     if (magicClassObject == null) 
     { 
      throw new ArgumentNullException(string.Format("Class {0} cannot be null.", magicType.Name.ToString())); 
     } 
     list.Insert(0, magicClassObject); 
     list.Add(magicClassObject); 
相关问题