2016-11-23 9 views
1

У меня есть требование, где я должен сериализовать следующую иерархию типов в YAMLКак сериализовать и десериализовать объект класса Type в C# в 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 
      } 
     }; 

Здесь я получаю исключение, как

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

Дополнительная информация: Исключение было брошено в мишенью invocation. {«Метод может быть вызван только для типа, для которого Type.IsGenericParameter является истинным."}

Пожалуйста, помогите!

+0

Когда я прокомментировал линии [Type = TypeOf (Int32)] в разделе Variable, он был успешно сериализованная – Anonymous

ответ

1

Это потому, что вы пытаетесь сериализовать System.Type. У этого типа много свойств, и некоторые из них генерируют исключение, которое вы видите. Это обсуждалось на issue #212, хотя в этом случае исправление было полностью избежать сериализации System.Type.

В идеале вы сможете зарегистрировать конвертер пользовательского типа для обработки System.Type и сериализовать его как строку, но из-за a shortcoming with the way the object graph is traversed свойство будет по-прежнему доступным.

Ваше лучшее решение, вероятно, чтобы обернуть System.Type внутри пользовательского класса, который сериализует, как вы хотите:

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

Редактировать

Выпуск указанных была исправлена. Если вы пытаетесь the latest pre-release package, вы сможете добиться того, что вы хотите, зарегистрировав обычай 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

Привет, есть ли способ сериализации сложных типов в C#, таких как DataTable, в YAML? Поскольку я очень новичок в YAML, не могли бы вы объяснить основы? Спасибо – Anonymous

+0

В принципе, техника такая же. Вы регистрируете пользовательский 'IYamlTypeConverter', который обрабатывает сериализацию и десериализацию. Но было бы лучше, если бы вы задали новый вопрос для этого, чтобы я мог правильно ответить. –