2

所以我有一个类,Texture2DProcessor,它继承了 IXmlSerializable 并隐式转换到 Texture2D

public static implicit operator Texture2D(Texture2DProcessor o)
{
    return o.Data;
}
public static implicit operator Texture2DProcessor(Texture2D o)
{
    return o == null ? null : new Texture2DProcessor(o);
}

然后我有一个结构 GunProperties,它包含一个带有 XmlElement 属性的 Texture2D 属性,其类型设置为 Texture2DProcessor

Texture2D _sideSprite;
[XmlElement(typeof(Texture2DProcessor))]
public Texture2D SideSprite
{
    get { return _sideSprite; }
    set { _sideSprite = value; }
}

我收到以下运行时错误

Cannot serialize member '...GunProperties.SideSprite' of type 'Microsoft.Xna.Framework.Graphics.Texture2D'

为什么 XmlSerializer 不使用 Texture2DProcessor 来读写 Xml 数据?

我也知道我的 ReadXml 和 WriteXml 方法可以正常工作,因为它可以正常工作并且我可以使用纹理。

Texture2D texture;
XmlSerializer serializer = new XmlSerializer(typeof(Texture2DProcessor));
serializer.Deserialize(new FileStream(path, FileMode.Open), texture);

我遇到这个麻烦的原因是我正在使用monogame,并且内容管道非常混乱,特别是对于自定义类型,除了这个问题之外,我一切正常。

4

1 回答 1

1

看起来这可能是 Mono 的XmlSerializer限制。我有一个可以在 .NET 下运行的小型测试应用程序,但不能在 Mono 3.0.6 下运行。

但这看起来很容易解决:

[XmlIgnore]
public Texture2D SideSprite { get; set; }

[XmlElement("SideSprite")]
[EditorBrowsable(EditorBrowsableState.Never)]
public Texture2DProcessor SideSpriteProcessor
{
    get { return SideSprite; }
    set { SideSprite = value; }
}

我们在我的 Noda Time 项目中遇到了同样的问题,因为 XML 序列化不能很好地与不可变类型混合。我在那里给出了几乎相同的建议

编辑:好的,所以这里有一些可以工作的示例代码

using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

public class Person
{
    public string Name { get; set; }
}

public class PersonWrapper : IXmlSerializable
{
    public Person Person { get; set; }

    public static implicit operator Person(PersonWrapper wrapper)
    {
        return wrapper == null ? null : wrapper.Person;
    }

    public static implicit operator PersonWrapper(Person person)
    {
        return new PersonWrapper { Person = person };
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        string name = reader.ReadString();
        reader.ReadEndElement();
        Person = new Person { Name = name };
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteString(Person.Name);
    }
}

public class Company
{
    [XmlElement(typeof(PersonWrapper))]
    public Person Director { get; set; }

    [XmlElement(typeof(PersonWrapper))]
    public Person Manager { get; set; }
}

class Test
{
    static void Main()
    {
        var serializer = new XmlSerializer(typeof(Company));

        var original = new Company
        {
            Director = new Person { Name = "Holly" },
            Manager = new Person { Name = "Jon" }
        };

        var writer = new StringWriter();
        serializer.Serialize(writer, original);
        Console.WriteLine("XML:");
        Console.WriteLine(writer.ToString());

        var reader = new StringReader(writer.ToString());
        var deserialized = (Company) serializer.Deserialize(reader);

        Console.WriteLine("Deserialized:");
        Console.WriteLine("Director: {0}", deserialized.Director.Name);
        Console.WriteLine("Manager: {0}", deserialized.Manager.Name);
    }
}
于 2013-05-18T07:04:09.497 回答