2012-04-05 4 views
3

Попытка добавить объект класса в список с использованием отражения, но при вызове метода Add с моим объектом класса в качестве параметра я получаю «Object не соответствует целевому типу»Списки рефлексии 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

+1

@CJxD: См. Http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx для некоторых аргументов. Возможно, вы даже не хотите показывать их непосредственно в виде списков - вы можете просто выставить определенные операции, такие как «AddProcessor», «AddMotherboard» и т. Д. Это зависит от того, какой уровень инкапсуляции вы хотите достичь. –

+0

Получите инструмент анализа кода и включите его в свой код. Он будет вопить в муках. От членов с теми же именами, что и типы, не используя свойства, выставляя конкретные типы ... Вы не делаете себе ничего подобного с помощью такого ярлыка. public List Процессоры {get; set;} (или, тем не менее, частный набор), вряд ли будет какой-то огромной необъяснимой нагрузкой. –

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); 
Смежные вопросы