Я сериализую универсальные типы с DataContractSerializer
. Он прекрасно работал до тех пор, пока класс не имел двух известных типов, которые являются двумя версиями универсального типа с различными интерфейсами в качестве универсального параметра.
Вот самый простой пример, который я мог бы быстро собрать. Существует два интерфейса (IInterfaceA
и IInterfaceB
), реализованные некоторыми типами (ImplementationA
и ImplementationB
). Существует универсальный тип Generic<T>
, который реализует некоторый другой интерфейс IOtherInterface
. И есть класс, который я хочу сериализовать, HereComesTrouble
, который содержит два члена данных этого интерфейса.
Я использовал атрибуты KnownType
для перечисления всех возможных конкретных типов, которые могут встречаться в графе сериализованных объектов. Generic<ImplementationA>
и Generic<ImplementationB>
перечислены , а не , поскольку эти типы никогда не будут существовать.
Это сообщение InvalidOperationException
, которое я получаю при запуске кода:
Тип 'Test.Generic`1 [Test.IInterfaceB]' нельзя добавить в список
известные типы, начиная с другого типа 'Test.Generic`1 [Test.IInterfaceA]' с
то же имя контракта данных
http://schemas.datacontract.org/2004/07/Test:GenericOfanyType'
уже присутствует. Если есть разные коллекции конкретного
type - например, List и Test [], они не могут быть оба добавлены
как известные типы. Попробуйте указать только один из этих типов для
дополнение к списку известных типов.
Как мне обойти эту проблему?
using System.IO;
using System.Runtime.Serialization;
namespace Test
{
internal interface IInterfaceA { }
internal interface IInterfaceB { }
[DataContract]
internal class ImplementationA : IInterfaceA { }
[DataContract]
internal class ImplementationB : IInterfaceB { }
internal interface IOtherInterface { }
[DataContract]
internal class Generic<T> : IOtherInterface
{
[DataMember]
public T GenericData { get; set; }
}
[DataContract]
[KnownType(typeof(ImplementationA))]
[KnownType(typeof(ImplementationB))]
[KnownType(typeof(Generic<IInterfaceA>))]
[KnownType(typeof(Generic<IInterfaceB>))] // <-- Removing this one line makes everything work.
internal class HereComesTrouble
{
[DataMember]
public IOtherInterface Member1 { get; set; }
[DataMember]
public IOtherInterface Member2 { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
var toSerialize = new HereComesTrouble();
var serializer = new DataContractSerializer(typeof(HereComesTrouble));
using (var memoryWriter = new MemoryStream())
serializer.WriteObject(memoryWriter, toSerialize); // <-- InvalidOperationException!
}
}
}