2016-11-23 12 views
1

私はYAMLに次の型階層をシリアル化する必要がある要件を持っている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 

追加情報:例外は、ターゲットによってスローされました呼び出し。{"メソッドは、Type.IsGenericParameterがtrueのTypeに対してのみ呼び出すことができます。"}

助けてください!

+0

を – 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登録することにより、あなたが望むものを達成することができるようになります:私は、行をコメントした場合、[タイプ= typeof演算(Int32)を、]変数のセクションでは、それが正常にシリアル化された

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

こんにちは、DataTableなどのC#で複雑な型をYAMLにシリアル化する方法はありますか?私はYAML初心者ですから、基礎を説明していただけますか?おかげで – Anonymous

+0

基本的に、技術は同じです。シリアライズとデシリアライズを処理するカスタム 'IYamlTypeConverter'を登録します。しかし、あなたが新しい質問をしてくれたら、それが正しいと答えることができればよいでしょう。 –

関連する問題