Как сериализовать список типов c generi, которые наследуются от класса non generi c - PullRequest
0 голосов
/ 18 июня 2020

У меня есть следующая структура классов:

[Serializable]
public abstract class TagConfiguration
{
    public abstract string Name { get; set; }

    // Other abstract properties

    public abstract object GetInitialValue();
    public abstract void SetInitialValue(object value);

    protected TagConfiguration() { }

    // Other methods not useful in the scope of this problem
}

[Serializable]
public class GenericTagConfiguration<T> : TagConfiguration
{
    public override string Name { get; set; }

    // Other abstract properties

    private T _initialValue;
    public T InitialValue
        {
            get => (T)GetInitialValue();
            set => SetInitialValue(value);
        }
        public override object GetInitialValue()
        {
            return _initialValue;
        }
        public override void SetInitialValue(object value)
        {
            _initialValue = (T)value;
        }

    public GenericTagConfiguration() : base() { }

    // Other methods not useful in the scope of this problem
}

Этот класс, как следует из названия, предназначен для конфигурации объекта Tag, который выглядит следующим образом:

[Serializable]
public abstract class Tag
{
    public abstract object GetConfiguration();
    public abstract void SetConfiguration(object value);
    public abstract object GetCurrentValue();
    public abstract void SetCurrentValue(object value);

    protected Tag() { }

    // Some abstract methods
}

[Serializable]
public class GenericTag<T> : Tag
{
    private GenericTagConfiguration<T> _configuration;
    public TagConfiguration Configuration
    {
        get => (GenericTagConfiguration<T>)GetConfiguration();
        set => SetConfiguration(value);
    }
    public override object GetConfiguration()
    {
        return _configuration;
    }
    public override void SetConfiguration(object value)
    {
        _configuration = (GenericTagConfiguration<T>)value;
    }

    private T _currentValue;
    public T CurrentValue
    {
        get => (T)GetCurrentValue();
        set => SetCurrentValue(value);
    }
    public override object GetCurrentValue()
    {
        return _currentValue;
    }
    public override void SetCurrentValue(object value)
    {
        _currentValue = (T)value;
    }

    public GenericTag() : base() { }

    // The same methods from Tag overridden
}

I должен иметь возможность экспортировать List<TagConfiguration> в файл XML, но проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда я пытаюсь это сделать, я получаю сообщение об ошибке:

Unhandled Exception: System.InvalidOperationException: There was an error generating the XML document. 
---> System.InvalidOperationException:The type GenericTagConfiguration[[System.Int32]] was not expected. 
Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

Я использую следующее код для попытки экспорта:

List<TagConfiguration> lstTagConf = new List<TagConfiguration>
{
    tagConf,
    tagConf2
};

XmlSerializer xs = new XmlSerializer(typeof(List<TagConfiguration>));
using (TextWriter tw = new StreamWriter(@"C:\Users\Administrator\Documents\listTag.xml"))
{
    xs.Serialize(tw, lstTagConf);
}

ВОПРОС

Причина, по которой я добавил класс Tag, заключается в том, что мне нужно иметь возможность импортировать и экспортировать List<Tag>, а также List<TagConfiguration>.

Нужно ли мне писать интерфейс для этого?

1 Ответ

0 голосов
/ 18 июня 2020

Ответ, который я нашел (благодаря jdweng и этот вопрос ), заключался в добавлении следующего перед классом TagConfiguration:

[XmlInclude(typeof(GenericTagConfiguration<int>)), ...] // as many different T as you would use
[Serializable]
public abstract class TagConfiguration
{
    // Same data
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...