【问题标题】:C# Reflection Lists: Object does not match target typeC# 反射列表:对象与目标类型不匹配
【发布时间】:2012-04-05 17:26:37
【问题描述】:

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

这是相关的 sn-p 代码(您现在可以假设 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...
}

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    您正在尝试在 PC 上调用 List.Add(Processor) - 您想在 字段的值上调用它

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

    但是,我个人建议您不要拥有这样的公共字段。考虑改用属性。

    【讨论】:

    • 成功了!每次我公开一个公共领域时,都会有人抱怨=P,这真是太神奇了。别担心,一旦我接近发布程序,它们将成为属性。我仍然不完全理解为什么它们应该是属性。
    • @CJxD:有关一些论点,请参阅 csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx。您甚至可能不想将它们直接公开为列表 - 您可能只想公开某些操作,例如 AddProcessorAddMotherboard 等。这取决于您想要达到的封装级别。
    • 获取代码分析工具并将其打开您的代码。它会痛苦地嚎叫。来自与类型同名的成员,不使用属性,公开具体类型......你没有用这种快捷方式给自己带来任何好处。公共列表 处理器 {get; set;} (或者更好的私有集合),几乎不是什么巨大的不合情理的负担。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-10-06
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多