Для такого класса:
public class A
{
public FrozenSet Foo { get; set; }
}
и этот XML:
1
2
3
Я пытаюсь десериализовать это как есть, но мой код выдает исключение:
System.InvalidOperationException — необходимо реализовать метод доступа по умолчанию для System.Collections.Frozen.FrozenSet`1 [...], поскольку он наследуется от ICollection.
Изменение A.Foo в HashSet позволяет мне десериализовать нормально, как и ожидалось. Я попытался использовать HashSet в качестве прокси для замороженного члена набора:
[XmlElement(ElementName = nameof(Foo))]
public HashSet FooProxy
{
get => Foo?.ToHashSet() ?? [];
set => Foo = value.ToFrozenSet();
}
но это приводит к другому исключению:
InvalidOperationException: в XML-документе (3, 8) есть ошибка [...] Методы ReadElementContentAs() нельзя вызвать для элемента, у которого есть дочерние элементы. Строка 3, позиция 8
Я не хочу использовать обычный хэш-набор, поскольку этот код используется для объекта настроек программы. Эти настройки будут считываться в нескольких потоках и много раз (не менее 100 000 проверок), поэтому мы ценим дополнительную скорость, которую FrozenSet предлагает по сравнению с HashSet.
Использование этого предложения (обертывание HashSet в другой класс и использование его в качестве типа прокси для целевого замороженного набора) позволило мне заставить что-то работать, но это делает XML и код немного более неуклюжим, чем я например.
Другие вопросы касаются незамороженных коллекций, которые не решают проблемы, которые кажутся уникальными для замороженных коллекций.
Полный, самый простой и работоспособный пример кода:
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; }
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... -frozenset