如何修复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);
}
}
}
我不熟悉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)。