Given a class like this:
public class A {
public FrozenSet Foo {get; set;}
}
with XML:
1
2
3
Trying to deserialize this as-is throws a System.InvalidOperationException with the message "You must implement a default accessor on System.Collections.Frozen.FrozenSet`1 [...] because it inherits from ICollection."
Changing A.Foo to a HashSet allows me to deserialize just fine as expected. I attempted using a HashSet as a proxy for the frozen set member:
[XmlElement(ElementName = nameof(Foo))]
public HashSet FooProxy
{
get => Foo?.ToHashSet() ?? [];
set => Foo = value.ToFrozenSet();
}
but this yields another InvalidOperationException with the message "There is an error in XML document (3, 8) [...] ReadElementContentAs() methods cannot be called on an element that has child elements. Line 3, position 8."
I don't want to use a regular hash set because this code is used for a program settings object. These settings will be read across multiple threads and many times (at least 100,000 checks), so the extra speed that FrozenSet offers over HashSet is appreciated.
Using the suggestion here (wrapping the HashSet in another class and using that as the proxy type for the target frozen set) allowed me to get something working, but it makes the XML and code a little more clunky than I like.
Other questions focus on non-frozen collections, which don't solve the problems which seem to be unique to frozen collections.
Full, most basic, runnable code sample:
using System.Collections.Frozen;
using System.Xml.Serialization;
var xml = """
1
2
3
""";
var xmlSeriailizer = new XmlSerializer(typeof(A));
StringReader reader = new StringReader(xml);
A a = (A)xmlSeriailizer.Deserialize(reader)!;
foreach (int i in a.Foo)
Console.WriteLine(i);
public class A
{
public FrozenSet Foo { get; set; }
}