SORU
26 AĞUSTOS 2009, ÇARŞAMBA


Arayüz özelliği XML serileştirme

Hale bir nesne var (aralarında) türünde bir özellik XML etmek istiyorumİModelObjectbir arabirim olan).

public class Example
{
    public IModelObject Model { get; set; }
}

Bu sınıfın bir nesne seri hale getirilmeye çalıştığınızda, aşağıdaki hatayı alıyorum:

Sorun bir arayüz olamaz seri olduğunu anlıyorum. Ancak, betonModelnesne türü bilinmeyen çalışma zamanı kadar.

DeğiştirmeİModelObjectarabirim soyut veya somut bir tip ve Xmlınclude ile kullanmak miras ile mümkündür, ama çirkin bir çözüm gibi görünüyor.

Herhangi bir öneriniz var mı?

CEVAP
3 EYLÜL 2009, PERŞEMBE


Bu tür bilgileri sadece çıkış içinde gömülü olmadığı Bildirge serileştirme doğal bir sınırlama var.

<Flibble Foo="10" /> geri dönüştürmek için çalışıyor

public class Flibble { public object Foo { get; set; } }

Nasıl seri hale getirici bir int gerekip gerekmediğini biliyor mu, bir dize, bir çift (veya başka bir şey)...

Bu işi yapmak için çeşitli seçenekler var ama eğer gerçekten zamanı kadar yaptığım en kolay yolu bilmiyorum eğer bu XmlAttributeOverrides kullanarak olması muhtemeldir.

Ne yazık ki bu sadece temel sınıflar, arabirimleri ile çalışır. Orada yapabileceğin en iyi ihtiyaçlarınız için yeterli değil hangi özelliğini göz ardı etmektir.

Eğer gerçekten arayüzleri ile kalmalı Eğer üç seçeneğiniz vardır:

Gizlemek ve başka bir özellik ile anlaşma

Çirkin, kazan Plaka ve çok sayıda tekrar hoş ama sınıfın çoğu tüketici sorunu ile uğraşmak zorunda değildir:

[XmlIgnore()]
public object Foo { get; set; }

[(XmlElement("Foo")]
[EditorVisibile(EditorVisibility.Advanced)]
public string FooSerialized 
{ 
  get { /* code here to convert any type in Foo to string */ } 
  set { /* code to parse out of get and make an instance of the proper type*/ } 
}

Bu bakım tam bir kabus olacak gibi

Ixmlserializable Uygulamak

Bu şeyler tam kontrol altına almak ilk seçenek benzer ama

  • Artıları
    • Kötü 'sahte' özellikleri etrafında asılı.
    • doğrudan xml yapısı/sürüm esneklik ekleyerek iletişim kurabilirsiniz
  • Eksileri
    • yeniden uygulamak sınıfındaki tüm diğer özellikleri için direksiyonu zorunda sona erebilir

Çaba çoğaltılması konuları ilk benzer.

Emlak sarma türü kullanmak için değiştirin

public sealed class XmlAnything<T> : IXmlSerializable
{
    public XmlAnything() {}
    public XmlAnything(T t) { this.Value = t;}
    public T Value {get; set;}

    public void WriteXml (XmlWriter writer)
    {
        if (Value == null)
        {
            writer.WriteAttributeString("type", "null");
            return;
        }
        Type type = this.Value.GetType();
        XmlSerializer serializer = new XmlSerializer(type);
        writer.WriteAttributeString("type", type.AssemblyQualifiedName);
        serializer.Serialize(writer, this.Value);   
    }

    public void ReadXml(XmlReader reader)
    {
        if(!reader.HasAttributes)
            throw new FormatException("expected a type attribute!");
        string type = reader.GetAttribute("type");
        reader.Read(); // consume the value
        if (type == "null")
            return;// leave T at default value
        XmlSerializer serializer = new XmlSerializer(Type.GetType(type));
        this.Value = (T)serializer.Deserialize(reader);
        reader.ReadEndElement();
    }

    public XmlSchema GetSchema() { return(null); }
}

Bu şey gibi (proje P) yer alacağı kullanarak:

public namespace P
{
    public interface IFoo {}
    public class RealFoo : IFoo { public int X; }
    public class OtherFoo : IFoo { public double X; }

    public class Flibble
    {
        public XmlAnything<IFoo> Foo;
    }


    public static void Main(string[] args)
    {
        var x = new Flibble();
        x.Foo = new XmlAnything<IFoo>(new RealFoo());
        var s = new XmlSerializer(typeof(Flibble));
        var sw = new StringWriter();
        s.Serialize(sw, x);
        Console.WriteLine(sw);
    }
}

hangi verir:

<?xml version="1.0" encoding="utf-16"?>
<MainClass 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <Foo type="P.RealFoo, P, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
  <RealFoo>
   <X>0</X>
  </RealFoo>
 </Foo>
</MainClass>

Bu sınıfın kullanıcıları her ne kadar, kazan plaka önler için belli ki daha hantal.

Mutlu bir ortam haline XmlAnything fikir birleştirme olabilir 'destek' ilk teknik özellik. Bu şekilde homurtu işlerin çoğunu sizin için yapılır ama sınıf tüketiciler içgözlem ile karışıklık ötesinde herhangi bir etkisi muzdarip.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Blunty

    Blunty

    13 Mart 2006
  • Gee Cee

    Gee Cee

    1 AĞUSTOS 2009
  • MatheusDosGames

    MatheusDosGa

    28 Aralık 2011