如何修复null子类实例与反射

本文关键字:反射 实例 子类 何修复 null | 更新日期: 2023-09-27 17:54:41

我有一个主实例存储各种子类实例与选项。

Class MainClass
{
    public bool b;
    public int i;
    public List l = new List();
    Class SubClass1
    {
        ...
    }
    public SubClass1 sub1 = new SubClass1();
    Class SubClass2
    {
        ...
    }
    public SubClass2 sub2 = new SubClass2();
}

现在,当启动时所有类都正确地初始化,然后设置一些选项,并将结果序列化。

当(出于各种原因)我必须更改实例的名称时,问题就出现了。例如SubClass2——> SubClassB因此,当反序列化时,SubClassB显然是空的。

所以我必须修正这个缺点,我已经考虑了反射。比如[pseudocode]

foreach(var subclass in MainClass)
{
    if(subclass is null)
    {
        Type subClassType = typeof(subclass);
        subclass = new subClassType();
    }
}

事先感谢您的帮助。

——从母鸡的提示中添加完整的解决方案——

private void CheckAndFixNullInstances()
{
    easyRunData.OptionsReport = null;
    Type fieldsType = typeof(EasyRunBinSerializableData);
    FieldInfo[] fields = fieldsType.GetFields(BindingFlags.Public | BindingFlags.Instance);
    for (int i = 0; i < fields.Length; i++)
    {
        string str = fields[i].Name + " " + fields[i].GetValue(easyRunData);
        if (fields[i].GetValue(easyRunData) == null)
        {
            string strFieldType = fields[i].FieldType.AssemblyQualifiedName;
            Type t = Type.GetType(strFieldType);
            object item;
            item = Activator.CreateInstance(t);
            fields[i].SetValue(easyRunData, item);
        }
    }
}

如何修复null子类实例与反射

我不熟悉xml反序列化过程,但您基本上想要的是循环遍历特定对象的所有字段,并用字段类型的新对象填充所有空字段。

要获得类型的所有字段,您必须使用合适的Type.GetFields过载。然后你可以循环你得到的FieldInfo对象并调用FieldInfo.GetValue方法。完成空检查后,您可以通过传递FieldInfo.FieldType属性作为参数,然后使用FieldInfo.SetValue方法创建Activator.CreateInstance方法的新对象,并将其存储在字段中。

上面的方法不起作用,因为您无法从null对象中获得任何类型信息。本质上,当您序列化对象时,您希望存储所期望的类的完全限定名。当你对它进行反序列化时,你就可以读取这个值了。如果对象为"null",则可以创建完全限定类型的实例。

注意:"null"用引号括起来,因为这里的"null"在语义上是指不存在的东西,也不一定是空对象。

NBB:我已经在一个Github项目中解决了这个问题,欢迎您使用(https://github.com/ruskindantra/extensions/blob/master/RuskinDantra.Extensions/DataStructures/XmlSerializableInterfaceList.cs)。