c# - 如何将 C# 中的 Type 类对象序列化和反序列化为 YAML?

标签 c# serialization deserialization yaml yamldotnet

我有一个要求,我必须将以下类型层次结构序列化为 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
    }
};

在这里我得到一个异常(exception)
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll

附加信息:调用的目标已抛出异常。{"只能在 Type.IsGenericParameter 为 true 的类型上调用方法。"}

请帮忙 !!

最佳答案

这是因为您正在尝试序列化 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);

关于c# - 如何将 C# 中的 Type 类对象序列化和反序列化为 YAML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40762139/

相关文章:

C# BackGroundWorker 异常 DoWork 事件未触发

python - JSON 转储 Decimal 不可序列化

android - 如何序列化矩阵

cocoa - 在 Dot Net 中归档对象并在 Cocoa 中取消归档

c# - 将内联 C# 转换为代码隐藏文件的工具

c# - 如何从 blazor 应用程序调用 Azure AD B2C 编辑配置文件用户流程?

c# - 显示 FolderBrowserDialog 后 SQLite 中的 EntryPointNotFoundException

multithreading - 使用MSBuild并行构建的问题

java - Json字符串反序列化为复杂的Java对象

c# - 将 JSON 反序列化为自定义列表