2016-11-23 3 views
1

Ich habe eine Verpflichtung, wo ich die folgende Art Hierarchie in YAML serialisiert habenWie serialisiert und deserialisiert ein Typklassenobjekt in C# in YAML?

 var Variable1 = new 
     { 
      Name = "Variable1", 
      Type = typeof(Int32), 
      OverWrite = true, 
      Value = 10 
     }; 
     var Variable2 = new 
     { 
      Name = "Variable1", 
      Type = typeof(Int32), 
      OverWrite = true, 
      Value = 10 
     }; 

     var Job = new 
     { 
      Name = "Job1", 
      JobID = 1, 
      JobState = "Draft", 
      JobStatus = false, 
      Parameters = new[] 
      { 
       Variable1, 
       Variable2 
      }, 
      LocalVariables = new[] 
      { 
       Variable1 
      } 
     }; 

Hier bekomme ich eine Ausnahme als

An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll 

Zusätzliche Informationen: Ausnahme wurde durch das Ziel, ein geworfen Aufruf. {"Methode kann nur für einen Typ aufgerufen werden, für den Type.IsGenericParameter wahr ist."}

Bitte helfen Sie !!

+0

Wenn ich die Zeile kommentiert [Type = typeof (Int32),] in der Variable Abschnitt, es war erfolgreich serialisiert – Anonymous

Antwort

1

Dies ist, weil Sie versuchen, eine System.Type zu serialisieren. Dieser Typ hat viele Eigenschaften und einige von ihnen werfen die Ausnahme, die Sie sehen. Dies wurde auf issue #212 diskutiert, obwohl in diesem Fall die Lösung war, die Serialisierung der System.Type vollständig zu vermeiden.

Idealerweise können Sie einen benutzerdefinierten Typkonverter registrieren, der System.Type verarbeitet und ihn als Zeichenfolge serialisiert, aber aufgrund von a shortcoming with the way the object graph is traversed wird weiterhin auf die Eigenschaft zugegriffen.

Ihre beste Lösung ist wahrscheinlich die System.Type innerhalb einer benutzerdefinierten Klasse zu wickeln, die, wie Sie wollen serialisiert: behoben wurde erwähnt

public struct SerializableType : IYamlConvertible 
{ 
    private Type type; 

    void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer) 
    { 
     var typeName = (string)nestedObjectDeserializer(typeof(string)); 
     type = typeName != null ? Type.GetType(typeName) : null; 
    } 

    void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer) 
    { 
     nestedObjectSerializer(type != null ? type.AssemblyQualifiedName : null); 
    } 

    public static implicit operator Type(SerializableType value) 
    { 
     return value.type; 
    } 

    public static implicit operator SerializableType(Type value) 
    { 
     return new SerializableType { type = value }; 
    } 
} 

bearbeiten

Die Frage. Wenn Sie the latest pre-release package versuchen, werden Sie in der Lage zu erreichen, was Sie wollen, indem Sie eine benutzerdefinierte Registrierung IYamlTypeConverter:

public class SystemTypeTypeConverter : IYamlTypeConverter 
{ 
    public bool Accepts(Type type) 
    { 
     return typeof(Type).IsAssignableFrom(type); 
    } 

    public object ReadYaml(IParser parser, Type type) 
    { 
     var scalar = parser.Expect<Scalar>(); 
     return Type.GetType(scalar.Value); 
    } 

    public void WriteYaml(IEmitter emitter, object value, Type type) 
    { 
     var typeName = ((Type)value).AssemblyQualifiedName; 
     emitter.Emit(new Scalar(typeName)); 
    } 
} 

// .... 

var serializer = new SerializerBuilder() 
    .WithTypeConverter(new SystemTypeTypeConverter()) 
    .Build(); 

var yaml = serializer.Serialize(new TypeContainer 
{ 
    Type = typeof(string), 
}); 

var deserializer = new DeserializerBuilder() 
    .WithTypeConverter(new SystemTypeTypeConverter()) 
    .Build(); 

var result = deserializer.Deserialize<TypeContainer>(yaml); 

Assert.Equal(typeof(string), result.Type); 
+0

Hallo, gibt es eine Möglichkeit, die komplexen Typen in C# wie DataTable in YAML zu serialisieren? Da ich mit YAML sehr Anfänger bin, kannst du bitte die Grundlagen erklären ?? Danke – Anonymous

+0

Grundsätzlich ist die Technik die gleiche. Sie registrieren einen benutzerdefinierten 'IYamlTypeConverter', der die Serialisierung und Deserialisierung behandelt. Aber es wäre besser, wenn Sie eine neue Frage dafür stellen würden, damit ich richtig antworten kann. –

Verwandte Themen