-
-
Notifications
You must be signed in to change notification settings - Fork 754
Closed
Milestone
Description
Bug description
In System.Linq the default ILookup<TKey, TElement> implementation returns an empty sequence when the provided key does not exist, per https://docs.microsoft.com/en-us/dotnet/api/system.linq.lookup-2.item?view=net-6.0#remarks.
However, when you roundtrip an ILookup<TKey, TElement> through MessagePack you end up with an instance that throws a KeyNotFoundException when the key does not exist.
Repro steps
using MessagePack;
var lookup = new[] { "foo" }.ToLookup(x => x);
var mc = new MyClass { Lookup = lookup };
byte[] bytes = MessagePackSerializer.Serialize(mc);
MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes);
Console.WriteLine("Original: " + mc.Lookup["bar"].Count());
Console.WriteLine("Deserialized: " + mc2.Lookup["bar"].Count());
[MessagePackObject]
public class MyClass
{
[Key(0)]
public ILookup<string, string> Lookup { get; set; }
}Expected behavior
This repro program should show:
Original: 0
Deserialized: 0
Actual behavior
Instead, it shows:
Original: 0
Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key 'bar' was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at MessagePack.Formatters.Lookup`2.get_Item(TKey key)
at Program.<Main>$(String[] args) in C:\Users\joelv\Desktop\MessagePackRepro\MessagePackRepro\Program.cs:line 9
C:\Users\joelv\Desktop\MessagePackRepro\MessagePackRepro\bin\Debug\net6.0\MessagePackRepro.exe (process 39896) exited with code -532462766.
- Version used: 2.3.85
- Runtime: .NET 6
Additional context
You can do a workaround with Contains but this requires two lookups.
using MessagePack;
var lookup = new[] { "foo" }.ToLookup(x => x);
var mc = new MyClass { Lookup = lookup };
byte[] bytes = MessagePackSerializer.Serialize(mc);
MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes);
Console.WriteLine("Original: " + mc.Lookup["bar"].Count());
Console.WriteLine("Deserialized: " + (!mc2.Lookup.Contains("bar") ? 0 : mc2.Lookup["bar"].Count()));
[MessagePackObject]
public class MyClass
{
[Key(0)]
public ILookup<string, string> Lookup { get; set; }
}Metadata
Metadata
Assignees
Labels
No labels