C# - Designer Serialisieren Probleme
-
03-07-2019 - |
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);
}
}
}
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 Blob
s (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.