如何使用反射修复空子类实例

How to fix null subclasses instances with reflection

我有一个主实例存储各种子classes实例,里面有选项。

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

现在,开始时所有 class 都已正确初始化,然后设置了一些选项,并序列化了结果。

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

所以我必须解决这个问题,而且我对反思也很认真。 像 [伪代码]

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

提前感谢您的帮助。

---为了完整性添加 thehennny 提示中的解决方案---

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

以上方法无效,因为您无法从空对象中获取任何类型信息。本质上,当您序列化对象时,您希望存储您期望的 class 的完全限定名称。然后,当您反序列化它时,您可以读取该值。如果对象是 "null",您可以创建完全限定类型的实例。

注意:请注意 "null" 在引号中,因为这里 "null" 在语义上用于表示不存在的东西,不一定是空对象。

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

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

要获取类型的所有字段,您必须使用 suitable Type.GetFields overload。 然后你可以遍历你得到的 FieldInfo 个对象并调用 FieldInfo.GetValue Method。 进行空检查后,您可以使用 Activator.CreateInstance Method by passing the FieldInfo.FieldType Property as parameter and store it in the field using the FieldInfo.SetValue Method.

创建一个新对象