Frage

Ich habe ein problem mit der Serialisierung meine Objekte und eingegrenzt haben das problem auf einen bestimmten Fall (siehe code unten).Ich war immer der folgende Fehler:

Fehler 1 Ungültige Resx-Datei.Konnte nicht geladen werden, geben Sie Serialisieren.Harness.Blob, Serialisieren, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", die in der .RESX-Datei.Sicherstellen, dass die erforderlichen Verweise wurden zu Ihrem Projekt Hinzugefügt.Line 129, position 5....

Nun das wirklich merkwürdige ist, dass ein Neustart von Visual Studio den Fehler verursacht, Weg zu gehen und den code zu arbeiten, aber dann, nach einem scheinbar zufälligen Anzahl von builds (in dem der Sprach-code nicht geändert) wird es brechen wieder auf.

Können Sie sehen, was ich falsch mache/zu verpassen?

Vielen Dank im Voraus,

Meto

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design; using System.ComponentModel.Design;

namespace Serialisation.Harness
{    

    [Serializable]
    public class Blob
    {
        public Blob()
        {
        }
    }

    [Serializable]
    public class Basic
    {

        private List<Blob> blobs;
        public List<Blob> Blobs
        {
            get { return blobs; }
            set { this.blobs= value; }
        }

        public Basic()
        {
            basics = new List<Blob>();
        }

    }

    public class BasicComponent : Component
    {

        private Basic basic = new Basic();

        private IContainer components = new Container();

        public List<Blob> Blobs
        {
            get { return basic.Blobs; }
            set { basic.Blobs= value; }
        }

        public BasicComponent(IContainer container)
        {
            container.Add(this);
        }

    }

}
War es hilfreich?

Lösung

Erste von alle, die Serializable Attribut ist nicht für die designer-Serialisierung.Beim serialisieren von Objekten, die designer serialisieren, um die Ressource-Datei, wenn Sie nicht wissen, wie zu schreiben, es an die designer-code.Dies schreibt es in die resx-als blob mit einem InstanceDescriptor für den Objekttyp Standard-Konstruktor (dieser verliert alle Eigenschaftswerte, die Sie vielleicht wollen Sie auch gehören).Dies ist, was passiert ist, für die Blobs Eigenschaft, wie die designer nicht serialisieren generische Listen schön (es muss wissen, wie die Serialisierung von arrays, obwohl).

Um weiterhin die Informationen in diese permanenten Objekte, die Sie zum erstellen einer TypeConverter das gibt einen anderen Konstruktor in der InstanceDescriptor (tatsächlich nimmt einige Zustand zu beschreiben, die Eigenschaften, wie Ihr Blobs Eigenschaft).Zum Beispiel, wenn Sie einen Konstruktor für Ihre BasicComponent Typs, der eine IEnumerable<Blob>, Sie könnten dann eine InstanceDescriptor zu diesem Konstruktor übergeben ein array von Blobs (du würdest erstellen Sie eine neue List<Blob> etwa, dass in den Konstruktor).Da der designer weiß, wie man beibehalten eines InstanceDescriptor um die code, und weil es weiß, wie es zu bestehen arrays code, es würde dann fügen Sie diese zu Ihrem designer code-eher als die resx.

Sie können auch implementieren CodeDomSerializer den code angeben, der verwendet wird, um zu beschreiben, die Instanz, die die designer verwenden können, um zu speichern Sie Ihre Objekt in den designer-code-eher als die resx.

Type Converter

Verwenden die Typ-Konverter Ansatz, Sie könnten so etwas tun:

public class BasicComponentTypeConverter : TypeConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        bool canConvert = base.CanConvertTo(context, destinationType);

        if (!canConvert &&
            (destinationType == typeof(InstanceDescriptor))
        {
            canConvert = true;
        }

        return canConvert;
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        object conversion = null;

        if (culture == null)
        {
            culture = CultureInfo.CurrentCulture;
        }

        BasicComponent component = value as BasicComponent;
        if (basicComponent != null)
        {
            if (destinationType == typeof(InstanceDescriptor))
            {
               // Note that we convert the blobs to an array as this makes for nicer persisted code output.
               // Without it, we might just get a resource blob which is not human-readable.
               conversion = new InstanceDescriptor(
                   typeof(BasicComponent).GetConstructor(new Type[] { typeof(IEnumerable<Blob>) }),
                   new object[] { basicComponent.Blobs.ToArray() },
                   true);
            }
        }

        if (conversion == null)
        {
            conversion = base.ConvertTo(context, culture, value, destinationType);
        }

        return conversion;
    }
}

Beachten Sie, dass Sie benötigen, zu schreiben, eine Art Konverter für die Blob geben Sie als gut.Befestigen Sie den Typ Konverter zu die Typ, nur erklären, sondern die TypeConverter Attribut auf die Klasse der Typ-Konverter konvertieren, D. H.BasicConverter für das Beispiel oben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top