This is because you are trying to serialize a System.Type
. That type has lots of properties and some of them throw the exception that you are seeing. This was discussed on issue #212, although in that case the fix was to completely avoid serializing the System.Type
.
Ideally, you would be able to register a custom type converter to handle System.Type
and serialize it as a string, but due to a shortcoming with the way the object graph is traversed, the property will still be accessed.
Your best solution is probably to wrap the System.Type
inside a custom class that serializes as you want:
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 };
}
}
Edit
The issue mentioned has been fixed. If you try the latest pre-release package, you will be able to achieve what you want by registering a custom 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);