Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何序列化IEnumerable<;char>;作为字符串&;混淆反序列化错误_C#_Xml_Serialization - Fatal编程技术网

C# 如何序列化IEnumerable<;char>;作为字符串&;混淆反序列化错误

C# 如何序列化IEnumerable<;char>;作为字符串&;混淆反序列化错误,c#,xml,serialization,C#,Xml,Serialization,假设我有以下简单的类: [XmlRoot] [XmlType("string")] public partial class eString : IEnumerable<char> { string AsString {get;set;} public IEnumerator<char> GetEnumerator() { return this.AsString.ToCharArray().ToList().GetEnumerat

假设我有以下简单的类:

[XmlRoot]
[XmlType("string")]
public partial class eString : IEnumerable<char>
{
    string AsString {get;set;}
    public IEnumerator<char> GetEnumerator()
    {
        return this.AsString.ToCharArray().ToList().GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.AsString.ToCharArray().GetEnumerator();
    }
    public void Add(char character)
    {
        this.AsString += character;
    }
}
[XmlRoot]
[XmlType(“字符串”)]
公共部分类限制:IEnumerable
{
字符串关联{get;set;}
公共IEnumerator GetEnumerator()
{
返回此.AsString.ToCharArray().ToList().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回此.AsString.ToCharArray().GetEnumerator();
}
公共无效添加(字符)
{
this.AsString+=字符;
}
}
还有一个namedValue类:

[XmlRoot]
public partial class eNamedValue: KeyValuePair<eString,object>
{...}
[XmlRoot]
公共部分类eNamedValue:KeyValuePair
{...}
最后

[XmlRoot]
public partial class eList<T>: List<eNamedValue>
{...}
[XmlRoot]
公共部分类eList:列表
{...}
现在,我使用以下XML序列化程序序列化eList或从eList继承的任何类:

    public static XDocument Serialize<T>(this T obj) where T: new()
    {
        Type tt = obj.GetType();
        XmlSerializer xsSubmit = new XmlSerializer(tt);
        StringWriter sww = new StringWriter();
        XmlWriter writer = XmlWriter.Create(sww);
        xsSubmit.Serialize(writer, obj);
        return XDocument.Parse(sww.ToString());
    }
publicstaticxdocument序列化(这个T对象),其中T:new()
{
类型tt=obj.GetType();
XmlSerializer xsSubmit=新的XmlSerializer(tt);
StringWriter sww=新StringWriter();
XmlWriter=XmlWriter.Create(sww);
xsSubmit.Serialize(writer,obj);
返回XDocument.Parse(sww.ToString());
}
序列化可以工作-但是我的eString被序列化为字符数组,所以我没有得到“字符串”,而是得到单个字符的值:

<eNamedList>
  <Key>99</Key>
  <Key>111</Key>
  <Key>100</Key>
  <Key>101</Key>...

99
111
100
101...

此外,关于反序列化(已解决,请参阅下面的更新#1):

publicstatict反序列化(此XDocumentXML),其中T:new()
{
var serializer=newxmlserializer(typeof(T));
T结果;
使用(TextReader=newStringReader(xml.ToString()))
{
结果=(T)序列化程序。反序列化(读取器);
}
返回结果;
}
我收到以下错误:

System.Runtime.Serialization.SerializationException:第1行位置111处出错。应为命名空间“”中的元素“eNamedList”。。遇到名称为“eNamedList”、命名空间为“”的“元素”

因此,我的问题变成:

  • 如何控制我的
    eString
    或任何
    IEnumerable
    的序列化,并始终将其序列化为字符串
  • 为什么,当元素名匹配时,反序列化会失败?(我只是缺少一个名称空间声明?)
  • 谢谢


    更新#1: 因此,我从eString中删除了
    IEnumerable
    接口,只保留了
    IEnumerable.GetEnumerator()
    方法,该方法允许我的字符串在foreach循环中用作
    IEnumerable
    ,但作为字符串序列化#赢


    另外,多亏了dbc,使用XML反序列化程序(而不是DataContract序列化程序)更新了原始帖子,反序列化工作正常。

    要回答您的问题:

  • 您可能不应该用自定义字符串解决方案重新发明轮子。无论如何,如果您想要(疯狂地)对(反)序列化进行高级控制,您可以实现IXmlSerializable,并自己做完全相同的事情

    [XmlRoot("string-wrapper")]
    public class CustomString : IXmlSerializable
    {
        public string Value { get; set; }
    
        public XmlSchema GetSchema()
        {
            return null; // GetSchema should not be used.
        }
    
        public void ReadXml(XmlReader reader)
        {
            reader.MoveToContent();
            bool isEmpty = reader.IsEmptyElement;
    
            reader.ReadStartElement();
            if (!isEmpty)
            {
                Value = reader.ReadString();
                reader.ReadEndElement();
            }
        }
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteString(Value);
        }
    }
    
  • 自定义字符串的序列化现在产生
    测试
    。我将在这篇文章的末尾发布一些测试代码

  • 您的反序列化可能已中断,因为XmlSerializer不知道您标记为serializable的IEnumerable实际上应该被视为字符串
  • 现在。。。忘了我刚才告诉你的吧。除非您有非常具体的格式要求,否则您不应该实现自己版本的字符串。内置的格式化程序知道更多的格式化技巧(),所以您可能应该让它完成它的工作

    序列化类是属性的用武之地,尽管我建议您切换到WFC数据契约,它一开始可能听起来很吓人,但实际上用更少的代码提供了更多。再说一次,我不确定您想要完成什么,但是请相信我,您不想养成手写XML的习惯

    如果您愿意,您可能会喜欢动态对象和ExpandoObject()。这些类型一起消除了所有类型,并允许您动态创建字典、数组、命名属性等等

    最后,简单的泛型!反序列化泛型类不是一项简单的任务。此外,你可能不需要这样做。如果需要自己的集合,请尝试System.collections.ObjectModel命名空间。您不必担心维护列表和实现接口,只需担心实际存储的内容:

    class DictionaryOfStringsAndObjects : KeyedCollection<string, object {...}
    class CollectionOfStrings : Collection<string> {...}
    

    类词典yofstringsandObjects:KeyedCollection回答您的问题:

  • 您可能不应该用自定义字符串解决方案重新发明轮子。无论如何,如果您想要(疯狂地)对(反)序列化进行高级控制,您可以实现IXmlSerializable,并自己做完全相同的事情

    [XmlRoot("string-wrapper")]
    public class CustomString : IXmlSerializable
    {
        public string Value { get; set; }
    
        public XmlSchema GetSchema()
        {
            return null; // GetSchema should not be used.
        }
    
        public void ReadXml(XmlReader reader)
        {
            reader.MoveToContent();
            bool isEmpty = reader.IsEmptyElement;
    
            reader.ReadStartElement();
            if (!isEmpty)
            {
                Value = reader.ReadString();
                reader.ReadEndElement();
            }
        }
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteString(Value);
        }
    }
    
  • 自定义字符串的序列化现在产生
    测试
    。我将在这篇文章的末尾发布一些测试代码

  • 您的反序列化可能已中断,因为XmlSerializer不知道您标记为serializable的IEnumerable实际上应该被视为字符串
  • 现在。。。忘了我刚才告诉你的吧。除非您有非常具体的格式要求,否则您不应该实现自己版本的字符串。内置的格式化程序知道更多的格式化技巧(),所以您可能应该让它完成它的工作

    序列化类是属性的用武之地,尽管我建议您切换到WFC数据契约,它一开始可能听起来很吓人,但实际上用更少的代码提供了更多。再说一次,我不确定您想要完成什么,但是请相信我,您不想养成手写XML的习惯

    如果您愿意,您可能会喜欢动态对象和ExpandoObject()。这些类型一起消除了所有类型,并允许您动态创建字典、数组、命名属性等等

    最后,ea
    public class CustomSerializer
    {
        public static void Test()
        {
            var obj = new CustomString {Value = "Random string!"};
            var serializer = new CustomSerializer();
            var xml = serializer.Serialize(obj);
            Console.WriteLine(xml);
    
            var obj2 = serializer.Deserialize<CustomString>(xml);
        }
    
        public string Serialize(object obj)
        {
            var serializer = new XmlSerializer(obj.GetType());
            using (var io = new StringWriter())
            {
                serializer.Serialize(io, obj);
                return io.ToString();
            }
        }
    
        public T Deserialize<T>(string xml)
        {
            var serializer = new XmlSerializer(typeof (T));
            using (var io = new StringReader(xml))
            {
                return (T)serializer.Deserialize(io);
            }
        }
    }