Cysharp / MemoryPack

Zero encoding extreme performance binary serializer for C# and Unity.
MIT License
3.21k stars 188 forks source link

ArrayTypeMismatchException: when using collections with interfaces #308

Open ptr1120 opened 1 month ago

ptr1120 commented 1 month ago

Hello, I am trying to serialize a class that holds a collection of objects given by an interface. But I always get ArrayTypeMismatchException Attempted to access an element as a type incompatible with the array. Any idea what I am doing wrong?

[Fact]
public void CollectionOfInterfaces()
{
    var f = new DynamicUnionFormatter<IMyInterface>(
        (0, typeof(MyClass)));

    MemoryPackFormatterProvider.Register(f);

    var one = new MyClass() { MyProperty = 999 };
    var myClass = new MyListHolder
    {
        Bases = new []{ one }
    };
    var bin1 = MemoryPackSerializer.Serialize(myClass);
}

[MemoryPackable]
public partial class MyListHolder
{
    public IReadOnlyCollection<IMyInterface> Bases { get; init; }
}

[MemoryPackable(GenerateType.NoGenerate)]
public partial interface IMyInterface
{
}

[MemoryPackable(GenerateType.Object)]
public partial class MyClass : IMyInterface
{
    public int MyProperty { get; set; }
}
neuecc commented 1 month ago

Thank you! I've confirmed, it is bug of implementation, if exists array's covariance throws runtime exception. I'll fix it.

For example, if you change to this will work fine.

var myClass = new MyListHolder
{
    Bases = new IMyInterface []{ one }
};

Also you can change like this

var myClass = new MyListHolder
{
    Bases = [one]
};