.NET XmlSerializer и вложенные классы в С#
Я столкнулся с некоторым удивительным поведением с использованием XmlSerializer в С#. Рассмотрим следующий фрагмент кода.
public class A : IEnumerable
{
public class B
{
[XmlAttribute]
public string PropA { get; set; }
[XmlElement]
public string PropB { get; set; }
}
public IEnumerator GetEnumerator ()
{
yield break;
}
}
class Program
{
static void Main (string[] args)
{
XmlSerializer serializer = new XmlSerializer(typeof(A.B));
XmlTextWriter writer = new XmlTextWriter(@"E:\temp\test.xml", Encoding.Default);
serializer.Serialize(writer, new A.B() { PropA = "one", PropB = "two" });
}
}
В этом примере я пытаюсь сериализовать экземпляр вложенного класса A.B, который сам по себе не использует контейнерный класс A. Но когда я пытаюсь построить XmlSerializer для него, выдается следующее исключение:
InvalidOperationException был необработанным:
Чтобы быть сериализуемым XML, типы, которые наследуют от IEnumerable, должны иметь реализация Add (System.Object) на всех уровнях их иерархия наследования. Test.A не реализует Add (System.Object).
XmlSerializer пытается применить ограничения сериализации к типу A, когда я на самом деле пытаюсь сериализовать тип A.B. Однако мое понимание заключается в том, что помимо привилегированного доступа к данным в экземплярах внешнего типа вложенный тип не является особым и ведет себя так, как если бы он находился в пространстве имен.
Является ли это понимание неправильным, а делает семантику вложенных типов или XmlSerializer оправдывает это поведение, или это похоже на ошибку в XmlSerializer?
В контексте семантики XmlSerializer существует ли какое-либо документированное требование, которое применяет ограничения XmlSerializer для всех внешних типов при применении к вложенному типу?
Ответы
Ответ 1
http://msdn.microsoft.com/en-us/library/vstudio/ms229027%28v=vs.100%29.aspx
Поскольку вложенный тип рассматривается как член типа объявления, вложенный тип имеет доступ ко всем другим членам в объявляющем типе.
Итак, если сериализатор хочет работать с A.B, ему также нужно определение A. Где выполняется проверка IEnumerable.
Не имеет значения, что B фактически не ссылается ни на что в A:)
Ответ 2
это IEnumerable, который создает здесь ограничения. Если вы добавите метод Add, как это было предложено по исключению, ваш код будет работать нормально. Опять же, это мало связано с XmlSerialization и больше с тем, как работает IEnumerable. Пожалуйста, поправьте меня, если я здесь. Проверьте это
для хорошего обсуждения того же самого.
Ответ 3
XmlSerializer предоставляет специальное обращение к классам, которые реализуют IEnumerable или ICollection.
подробнее здесь:
XmlSerializer и IEnumerable: возможна сериализация без конструктора без параметров: ошибка?
Ответ 4
Вероятно, это очень сложная проблема во время выполнения сериализации, но у меня нет никаких хороших объяснений этому поведению. Я чувствую, что ограничение IEnumerable не распространяется на класс B.