【问题标题】:Serialize/Deserialize a dynamic object序列化/反序列化动态对象
【发布时间】:2014-08-29 00:18:26
【问题描述】:

我有以下课程:

    public abstract class Animal
    {
        public Animal() { _myType = getAnimal(this.GetType().Name); }
        private dynamic _myType; 
        public dynamic myType { get { return _myType; } }
    }

    public class Cat : Animal
    {
        public Cat() : base() { }
    }

及其辅助函数:

    public static T CreateAnimal<T>(string animal)
    {
        Type type = Type.GetType(typeof(Form1).FullName + "+" + animal);
        return (T)Activator.CreateInstance(type);
    }
    public static dynamic getAnimal(string name)
    {
        dynamic theAnimal = Activator.CreateInstance(MyAnimals); // Will default to 'Cat'
        FieldInfo fi = MyAnimals.GetField(name);
        int iEnum = (int)fi.GetValue(MyAnimals);
        return Enum.ToObject(MyAnimals, iEnum);
    }

它从动态创建的枚举“MyAnimals”中获取“myType”:

    public static Type MyAnimals;

    public static void CreateAnimalEnum()
    {
        // Get the current application domain for the current thread.
        AppDomain currentDomain = AppDomain.CurrentDomain;

        // Create a dynamic assembly in the current application domain,  
        // and allow it to be executed and saved to disk.
        AssemblyName aName = new AssemblyName("TempAssembly");
        AssemblyBuilder ab = currentDomain.DefineDynamicAssembly(
            aName, AssemblyBuilderAccess.Run);

        // Define a dynamic module in "TempAssembly" assembly. For a single-
        // module assembly, the module has the same name as the assembly.
        ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);

        // Define a public enumeration with an underlying type of Integer.
        EnumBuilder eb = mb.DefineEnum("MyAnimalType", TypeAttributes.Public, typeof(int));

        var types = new List<Type>();
        int Count = 0;
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            try
            {
                types.AddRange(assembly.GetTypes().Where(x => x.IsSubclassOf(typeof(Animal))));
            }
            catch { }
        foreach (var type in types)
            eb.DefineLiteral(type.Name, Count++);

        // Create the type and save the assembly.
        MyAnimals = eb.CreateType();
    }

所以现在当我创建一只猫时,我无法序列化它。 “InvalidOperationException:生成 XML 文档时出错。”我尝试过使用 DynamicObject,并且找到了一个动态帮助器类 (https://gist.github.com/martinnormark/2574972),但是当我想序列化一个封装在另一个类中的 Cat 对象时,这并没有帮助。

    public static bool Save(Animal animal)
    {
        System.Xml.Serialization.XmlSerializer ListSer = new System.Xml.Serialization.XmlSerializer(typeof(Animal));
        System.IO.StreamWriter mywriter = new System.IO.StreamWriter(@"test.txt",  false);
        ListSer.Serialize(mywriter, animal);
        mywriter.Flush();
        mywriter.Close();
        return true;
    }

    public Form1()
    {
        InitializeComponent();
        GetEDIDeviceTypesEnums();

        Animal c = new Cat();
        Save(c);

        // This way fails too
        dynamic cat = CreateAnimal<Animal>("Cat");
        Save(cat);
    }

为了序列化 Cat,我缺少什么?

【问题讨论】:

    标签: c# serialization dynamic xml-serialization


    【解决方案1】:

    XMLSerializer 需要提前知道它可以序列化哪些类型;如果你在一个抽象类上初始化一个 XMLSerializer,它只会知道如何序列化这个类而不知道任何继承它的东西。

    XMLSerializer 有另一个构造函数,允许您输入一个额外类型的数组,以便在尝试序列化时使用。您可以从 GetAssemblies 动态构建该类型数组(类似于您构建自定义 MyAnimals 枚举所做的操作):

        public static bool Save(Animal animal)
        {
            var lListOfAnimals = (from lAssembly in AppDomain.CurrentDomain.GetAssemblies()
                             from lType in lAssembly.GetTypes()
                             where typeof(Animal).IsAssignableFrom(lType)
                             select lType).ToArray();
    
            System.Xml.Serialization.XmlSerializer ListSer = new System.Xml.Serialization.XmlSerializer(typeof(Animal), lListOfAnimals);
    

    代码直接取自Yahoo Serious 中的this thread 答案。正如 Yahoo Serious 所提到的,如果您经常调用 Save,以这种方式使用 Reflection 可能会导致性能下降,因此您可能会缓存 Animal 类型的数组,而不是每次序列化时都重新构建它。

    【讨论】:

    • 我不知道你用什么谷歌搜索来找到这个。我一直在寻找一整天。非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    相关资源
    最近更新 更多