Ответ 1
Во-первых, [Serializable] attr не имеет ничего общего с XmlSerializer. Это красная сельдь. [Serializable] имеет смысл для System.Runtime.Serialization, а XmlSerializer - в System.Xml.Serialization. Если вы украшаете свой класс с помощью [Serializable] и ваших членов с помощью [XmlIgnore], вы, вероятно, путаете себя или других читателей вашего кода.
XmlSerialization в .NET очень гибкая. В зависимости от того, как выполняется сериализация, прямо или косвенно, скажем, во время выполнения веб-сервисов - у вас есть разные способы управления вещами.
Один из вариантов заключается в использовании шаблона propertyNameSpecified для включения или выключения свойства в XML-сериализации. Предположим, что у вас есть этот код:
public class TypeA
{
public DateTime LastModified;
[XmlIgnore]
public bool LastModifiedSpecified;
}
Затем, если LastModifiedSpecified является ложным в экземпляре, поле LastModified не будет сериализовано для этого экземпляра. В конструкторе для вашего типа вы можете установить LastModifiedSpecified, чтобы всегда быть истинным в базовом типе и всегда false в производном типе. Фактическое значение boolean - LastModifiedSpecified - никогда не становится сериализованным, поскольку оно помечено как XmlIgnore.
Этот небольшой трюк зарегистрирован здесь.
Другой вариант - использовать XmlAttributeOverrides, что является способом динамического предоставления набора атрибутов сериализации XML (таких как XmlElementAttribute, XmlIgnoreAttribute, XmlRootAttribute и т.д.) - динамическое предоставление этих атрибутов сериализатору во время выполнения. XmlSerializer вместо проверки самого типа для этих атрибутов просто просматривает список атрибутов переопределения, предоставляемых его конструктору.
var overrides = new XmlAttributeOverrides();
// ....fill the overrides here....
// create a new instance of the serializer specifying overrides
var s1 = new XmlSerializer(typeof(Foo), overrides);
// serialize as normal, here.
Это показано более подробно здесь.
В вашем случае вы должны предоставить атрибут XmlIgnoreAttribute в качестве переопределения, но только при сериализации производного типа. (или что-то еще). Это работает только тогда, когда вы непосредственно создаете экземпляр XmlSerializer - это не сработает, если сериализация будет выполняться неявно с помощью среды выполнения, как с веб-службами.
Ура!