Хорошей ссылкой на процессе разработки, который сохраняет стабильность соединительной линии и действительно все работает в ответвлениях, является Divmod Окончательная Качественная Система Разработки . Быстрая сводка:
, Они используют SVN для этого, но это могло легко быть сделано с любой из распределенных систем управления версиями.
Вы можете попробовать использовать DataContractSerializer :
public interface A
{
}
public class B : A
{
}
public class C : A
{
}
class Program
{
static void Main(string[] args)
{
List<A> list = new List<A>(new A[] { new B(), new C() });
var serializer = new DataContractSerializer(
list.GetType(), new[] { typeof(B), typeof(C) });
var sb = new StringBuilder();
using (var stringWriter = new StringWriter(sb))
using (var writer = XmlWriter.Create(stringWriter))
{
serializer.WriteObject(writer, list);
}
using (var stringReader = new StringReader(sb.ToString()))
using (var reader = XmlReader.Create(stringReader))
{
list = (List<A>)serializer.ReadObject(reader);
}
}
}
Предполагая, что вы используете встроенную сериализацию XML .net, вам следует взглянуть на следующий атрибут:
System.Xml.Serialization.XmlIncludeAttribute
Он позволяет указать сериализатору включать другие типы при сериализации / десериализации.
Добавление новых типов в список без обновления метаданных сериализации - частый источник ошибок, убедитесь, что у вас есть адекватное покрытие тестами.
Я бы использовал абстрактный класс вместо интерфейса (поскольку нельзя сериализовать тип интерфейса), тогда вместо жесткого кодирования типа с использованием атрибута XmlInclude я бы добавил известные типы для XmlSerializer в методах Serial и Deserialize, например:
string listXml = Serialize<List<A>>(ListA, new Type[] { typeof(B), typeof(C) });
List<IA> NewList = Deserialize<List<A>>(listXml, new Type[] { typeof(B), typeof(C) });
private static T Deserialize<T>(string Xml, Type[] KnownTypes)
{
XmlSerializer xs = new XmlSerializer(typeof(T),KnownTypes);
StringReader sr = new StringReader(Xml);
return (T)xs.Deserialize(sr);
}
private static string Serialize<T>(Object obj, Type[] KnownTypes)
{
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
XmlSerializer xs = new XmlSerializer(typeof(T), KnownTypes);
xs.Serialize(sw, obj);
}
return sb.ToString();
}
Да, но вам нужно поиграть с атрибутами XmlElement, XmlRoot и XmlArray. Каждому типу требуется собственное имя элемента.
РЕДАКТИРОВАТЬ: Пример кода. Все классы являются производными от общего базового класса.
Вот пример кода:
[XmlRoot(ElementName="Root")]
public sealed class SomeObject
{
private BaseObject _Object;
[XmlElement(Type=typeof(App.Projekte.Projekt), ElementName="Projekt")]
[XmlElement(Type=typeof(App.Projekte.Task), ElementName="Task")]
[XmlElement(Type=typeof(App.Projekte.Mitarbeiter), ElementName="Mitarbeiter")]
public BaseObject Object
{
get
{
return _Object;
}
set
{
_Object = value;
}
}
}
РЕДАКТИРОВАТЬ: удалить атрибут сериализации, так как он не нужен (но необходим в моем проекте, откуда взят код)
Для вашего случая создайте абстрактный класс, который реализует ваш интерфейс, например:
abstract class Abs : A
, а затем наследуйте свои классы от Abs
public class B : Abs
public class C : Abs
и Список списка;
теперь используйте XmlIncludeAttribute для добавления ваших типов в массив типов XmlSerializer.
XmlSerializer
не работает с интерфейсами. Таким образом, вы можете:
преобразовать интерфейс в абстрактный класс, а затем использовать для него XmlIncludeAttribute
или указать KnownTypes для XmlSerializer
или
реализовать IXmlSerializable
для родительского тип
или
Рассмотрите возможность использования DataContractSerializer
из .NET 3.0