.Net Framework mscorlib.dll GetProperty вызывает ошибку из-за своего кэша при сериализации объекта с использованием Microsoft.Core.Avro - PullRequest
0 голосов
/ 18 января 2019

Я не знаю, как объяснить эту проблему на самом деле.

Я использую Microsoft.Core.Avro.dll. Я скачал из диспетчера пакетов Nuget, он на https://github.com/dougmsft/microsoft-avro.

Я сделал простое приложение. Я пытался создать много случаев для объяснения проблемы. Выдает ошибку при десериализации объекта, сериализованного после попытки получить свойство Type с помощью GetProperty. Я думаю, что это связано со свойством строкового типа. Я хочу поделиться кодом здесь, но это немного дольше. Я разделяю только несколько случаев здесь. Я делюсь всем делом с моим заявлением.

https://ufile.io/6xf9a

    [Test]
    public static void Test7()
    {
        // this throws an exception that is 'Unexpected end of stream: '17' bytes missing.'
        var f = new Foo7 { P1 = 1, P2 = 2, PP2 = 22, P3 = "test" };

        PropertyInfo p1 = f.GetType().GetProperty("P1");
        PropertyInfo p2 = f.GetType().GetProperty("P2");
        PropertyInfo p3 = f.GetType().GetProperty("P22");
        PropertyInfo p4 = f.GetType().GetProperty("P3");
        Stream s1 = Helper.Serialize(f);
        var s2 = Helper.Deserialize<Foo7>(s1);
        Assert.True(Helper.Equal(f, s2));
    }

    [Test]
    public static void Test7_1()
    {
        // Assert returns false, These objects are not the same.
        var f = new Foo7_1 { P1 = 1, P2 = 2, PP2 = 3, P3 = "test" };

        PropertyInfo p1 = f.GetType().GetProperty("P1");
        PropertyInfo p2 = f.GetType().GetProperty("P2");
        PropertyInfo p3 = f.GetType().GetProperty("P22");
        PropertyInfo p4 = f.GetType().GetProperty("P3");
        Stream s1 = Helper.Serialize(f);
        var s2 = Helper.Deserialize<Foo7_1>(s1);
        Assert.True(Helper.Equal(f, s2));
    }

    [Test]
    public static void Test7_2()
    {
        // Assert returns true. This is correct.
        var f = new Foo7_2 { P1 = 1, P2 = 2, PP2 = 22, P3 = "test" };

        var x = typeof(Foo7_2).GetProperties().ToList();

        PropertyInfo p1 = f.GetType().GetProperty("P1");
        PropertyInfo p2 = f.GetType().GetProperty("P2");
        PropertyInfo p3 = f.GetType().GetProperty("P22");
        PropertyInfo p4 = f.GetType().GetProperty("P3");
        Stream s1 = Helper.Serialize(f);
        var s2 = Helper.Deserialize<Foo7_2>(s1);
        Assert.True(Helper.Equal(f, s2));
    }

    public class Foo7
{
    public int P1 { get; set; }
    public long P2 { get; set; }
    public long PP2 { get; set; }
    public string P3 { get; set; }
}


public class Foo7_1
{
    public int P1 { get; set; }
    public long P2 { get; set; }
    public long PP2 { get; set; }
    public string P3 { get; set; }
}

public class Foo7_2
{
    public int P1 { get; set; }
    public long P2 { get; set; }
    public long PP2 { get; set; }
    public string P3 { get; set; }
}

// https://github.com/dougmsft/microsoft-avro
    public static Stream Serialize<T>(T obj)
    {
        if (obj == null) return null;
        var avroSerializerSettings = new AvroSerializerSettings
                                     {
                                         GenerateDeserializer = false,
                                         GenerateSerializer = true,
                                         Resolver = new AvroPublicMemberContractResolver(),
                                         UsePosixTime = false,
                                         KnownTypes = new List<Type> { typeof(T) },
                                         UseCache = true,
                                         Surrogate = null
                                     };

        IAvroSerializer<T> avroSerializer = AvroSerializer.Create<T>(avroSerializerSettings);
        var mem = new MemoryStream();
        avroSerializer.Serialize(mem, obj);
        return new MemoryStream(mem.ToArray());
    }

    public static T Deserialize<T>(Stream stream)
    {
        stream.Position = 0;
        var avroSerializerSettings = new AvroSerializerSettings
                                     {
                                         GenerateDeserializer = true,
                                         GenerateSerializer = false,
                                         Resolver = new AvroPublicMemberContractResolver(),
                                         UsePosixTime = false,
                                         KnownTypes = new List<Type> { typeof(T) },
                                         UseCache = true,
                                         Surrogate = null
                                     };

        IAvroSerializer<T> avroSerializer = AvroSerializer.Create<T>(avroSerializerSettings);
        T o = avroSerializer.Deserialize(stream);
        return o;
    }

        public static bool Equal(Foo7 t1, Foo7 t2)
    {
        if (t1.P1 != t2.P1) return false;
        if (t1.P2 != t2.P2) return false;
        if (t1.PP2 != t2.PP2) return false;
        if (t1.P3 != t2.P3) return false;

        return true;
    }

    public static bool Equal(Foo7_1 t1, Foo7_1 t2)
    {
        if (t1.P1 != t2.P1) return false;
        if (t1.P2 != t2.P2) return false;
        if (t1.PP2 != t2.PP2) return false;
        if (t1.P3 != t2.P3) return false;

        return true;
    }

    public static bool Equal(Foo7_2 t1, Foo7_2 t2)
    {
        if (t1.P1 != t2.P1) return false;
        if (t1.P2 != t2.P2) return false;
        if (t1.PP2 != t2.PP2) return false;
        if (t1.P3 != t2.P3) return false;

        return true;
    }

1 Ответ

0 голосов
/ 18 января 2019

Мне не понятно, почему это происходит, нужно заглянуть глубже к AvroPublicMemberContractResolver.

Но я смог исправить ваши тесты, позвонив f.GetType().GetProperties() перед сериализацией данных.

...