【问题标题】:C# [XmlElement] attribute doesn't implicitly cast Type?C# [XmlElement] 属性不隐式转换类型?
【发布时间】:2013-05-18 06:59:43
【问题描述】:

所以我有一个类,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);

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

【问题讨论】:

    标签: c# xml xml-serialization implicit-conversion monogame


    【解决方案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 序列化不能很好地与不可变类型混合。我已经在那里给了很多same advice

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

    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);
        }
    }
    

    【讨论】:

    • 哇,我没想到我的纹理处理器有一个单独的属性。这个“[EditorBrowsable(EditorBrowsableState.Never)]”是否使它不会出现在智能中?
    • @DanielJohnson:是的。您可以仍然从代码中引用它,但希望人们不会:)
    • 如果我可以在一个变量上使用一个属性以使其使用处理器,那就太好了。它在这个link
    • @DanielJohnson:我承认我不明白那个版本是如何工作的,但你的不明白。我更惊讶的是,这比你的行不通。唔。稍后我会看看我是否可以进一步调查,好像我们可以在野田时间用这种方式解决它,这对我也很有用。
    • 我认为这与它是一个泛型类有关,并且隐式转换使用泛型类型,所以当你把它放在 XmlElement 中时,它会将它视为子类
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 2021-06-08
    • 2014-02-28
    相关资源
    最近更新 更多