如何序列化List(诺基亚映像SDK)
本文关键字:诺基亚 映像 SDK IFilter 序列化 List | 更新日期: 2023-09-27 18:30:55
我正在尝试保存使用XML序列化应用于图像的IFilter(接口类型)列表,以便用户可以从他离开的地方编辑相同的图像。
[XmlRoot]
public class ImageProperties
{
public string ImageName { get; set; }
public string ImageFilePath { get; set; }
public List<IFilter> Filters { get; set; }
}
这可能吗?有没有其他选择可以做同样的事情?
你可以
使用IXmlSerializable
来实现这一点......假设你可以改变ImageProperties
类。
序列化后,可以通过查看每个筛选器实例并查询它来获取类型。您可以将此类型信息存储在 XML 中,以便在读取它时知道它是哪种类型,然后只需为每个筛选器调用默认的 XML 序列化程序。
这是一个可能的实现。
public class ImageProperties : IXmlSerializable
{
public string ImageName { get; set; }
public string ImageFilePath { get; set; }
public List<IFilter> Filters { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
string startEle = reader.Name;
reader.ReadStartElement();
Filters = new List<IFilter>();
do
{
switch (reader.Name)
{
case "imgName":
ImageName = reader.ReadElementContentAsString();
break;
case "imgFilePath":
ImageFilePath = reader.ReadElementContentAsString();
break;
case "filters":
reader.ReadStartElement("filters");
while (reader.Name.Equals("iFilter"))
{
XmlSerializer filterSerializer = new XmlSerializer(Type.GetType(reader.GetAttribute("type")));
reader.ReadStartElement("iFilter");
Filters.Add((IFilter)filterSerializer.Deserialize(reader));
reader.ReadEndElement();
}
reader.ReadEndElement();
break;
default:
reader.ReadOuterXml();
break;
}
} while (reader.Name != startEle);
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteElementString("imgName", ImageName);
writer.WriteElementString("imgFilePath", ImageFilePath);
writer.WriteStartElement("filters");
foreach (IFilter filter in Filters)
{
writer.WriteStartElement("iFilter");
writer.WriteAttributeString("type", filter.GetType().FullName);
XmlSerializer filterSerializer = new XmlSerializer(filter.GetType());
filterSerializer.Serialize(writer, filter);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
}
如果您有不同类型的筛选器,则会调用实际类型的默认序列化程序,以便记录它们的唯一属性。
例如,使用这些可用的筛选器类:
public interface IFilter
{
string SomeCommonProp { get; set;}
}
[XmlRoot("myFilter")]
public class MyFilter : IFilter
{
[XmlElement("somemyFilterProp")]
public string SomeMyFilterProp { get; set; }
[XmlElement("someCommonProp")]
public string SomeCommonProp { get; set;}
}
[XmlRoot("myOtherFilter")]
public class MyOtherFilter : IFilter
{
[XmlElement("someOtherFilterProp")]
public string SomeOtherFilterProp { get; set; }
[XmlElement("someCommonProp")]
public string SomeCommonProp { get; set;}
}
可以使用如下方式将 IFilter 中的两种不同类型的筛选器序列化和反序列化为 xml。
static void Main(string[] args)
{
ImageProperties props = new ImageProperties();
props.ImageName = "img.png";
props.ImageFilePath = "c:''temp''img.png";
props.Filters = new List<IFilter>();
props.Filters.Add(new MyFilter() { SomeMyFilterProp = "x", SomeCommonProp ="p" });
props.Filters.Add(new MyOtherFilter() { SomeOtherFilterProp = "y", SomeCommonProp ="p" });
XmlSerializer s = new XmlSerializer(typeof(ImageProperties));
using (StreamWriter writer = new StreamWriter(@"c:'temp'imgprops.xml"))
s.Serialize(writer, props);
using (StreamReader reader = new StreamReader(@"c:'temp'imgprops.xml"))
{
object andBack = s.Deserialize(reader);
}
Console.ReadKey();
}
这将生成如下所示的 XML。
<?xml version="1.0" encoding="utf-8"?>
<ImageProperties>
<imgName>img.png</imgName>
<imgFilePath>c:'temp'img.png</imgFilePath>
<filters>
<iFilter type="SomeNameSpace.Whatever.MyFilter">
<myFilter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<somemyFilterProp>x</somemyFilterProp>
<someCommonProp>p</someCommonProp>
</myFilter>
</iFilter>
<iFilter type="SomeNameSpace.Whatever.MyOtherFilter">
<myOtherFilter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<someOtherFilterProp>y</someOtherFilterProp>
<someCommonProp>p</someCommonProp>
</myOtherFilter>
</iFilter>
</filters>
</ImageProperties>
No.接口实例无法序列化。它不知道要"反序列化"到的实现。在这种情况下,它将需要一个具体的类或自定义序列化。