由于dll不同,克隆/序列化会产生错误的类

时间:2012-05-31 13:52:45

标签: c# generics xml-serialization

我有一个dll库TaskLibrary.dll,其中一个Execution类正在执行一些Operation和一个类ParallelizeExecution,只需一个Execution,就可以克隆它执行多个Run实例的Execution方法。

Clone类的Execution方法通过转换xml中的Execution并将其恢复为正常作为新实例来实现

public Execution{
    List<AOperation> operations;

    public Run(){
        foreach(var op in operations){
            //...do stuff...
        }
    }

    public Execution Clone(){
        MyXmlSerializer.DeserializeObject<Execution>(
                MyXmlSerializer.SerializeObject(this));
    }
}

public ParallelizeExecution{
    List<Execution> toRun;
    public RunParallel(Execution e,int numExecutions){
        toRun=new List<Execution>();

        for(var i=0;i<numExecutions;i++){
            toRun.Add(e.Clone());
        }
    }
}

Execution类是可序列化的,每个实现Operation的类都是可序列化的。这是通过使用所有AOperation实现扩展的抽象类(IOperation)获得的,使用XmlInclude注释使MyXmlSerializer适用于每个IOperation

[XmlInclude(typeof(Operation1))]
[XmlInclude(typeof(Operation2))]
public abstract class AOperation:IOperation{
    ...
}

现在我有一个引用TaskLibrary.dll的新项目。我需要在Execution

中添加一种新的操作
public class Operation3: Operation2 {
}

一次执行一切正常,但是当我使用ParallelizeExecution时,Operation3被正确序列化为Operation2,从而执行了不需要的Run方法。如何向AOperation类添加新类型的Execution,并期望它能够正确序列化并在Execution中运行?

如何在不改变Execution类序列化的方式的情况下避免出现问题?

警告:我知道可以使用Reflection来xmlserialize任何扩展给定的tipe,但我宁愿学习如何使用标准OOP(如果可能的话)这样做。

编辑:我可以修改TaskLibrary.dll,但我宁愿避免这种方法,它会使我学习新事物和帮助社区的努力无效,而且重新分配这些内容会非常痛苦。那些已经使用它的库。

1 个答案:

答案 0 :(得分:1)

您可以使用XmlSerializer constructor的extraTypes参数。使用反射查找所有相关类型,并使用完整列表创建XmlSerializer。整个过程是here,但为了后人的目的:

// use reflection to get all derived types
List<type> knownTypes = new List<type>();

// Iterate over whichever assembly has your types.
foreach(Type t in Assembly.GetExecutingAssembly().GetTypes())
    if (typeof(Car).IsAssignableFrom(t) || 
        typeof(Wheel).IsAssignableFrom(t) ||
        typeof(Door).IsAssignableFrom(t))
       knownTypes.Add(t);

// prepare to serialize a car object
XmlSerializer serializer = new XmlSerializer(typeof(Car), knownTypes.ToArray());