Использование дженериков с XmlSerializer

При использовании XML-сериализации в C# я использую такой код:

public MyObject LoadData()
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));
    using (TextReader reader = new StreamReader(settingsFileName))
    {
        return (MyObject)xmlSerializer.Deserialize(reader);
    }
}

(и аналогичный код для десериализации).

Это требует кастинга и не очень приятно. Есть ли способ напрямую в .NET Framework использовать дженерики с сериализацией? То есть написать что-то вроде:

public MyObject LoadData()
{
    // Generics here.
    XmlSerializer<MyObject> xmlSerializer = new XmlSerializer();
    using (TextReader reader = new StreamReader(settingsFileName))
    {
        // No casts nevermore.
        return xmlSerializer.Deserialize(reader);
    }
}

person Arseni Mourzenko    schedule 19.04.2010    source источник
comment
Общий XmlSerializer, как показано в приведенном выше примере, не существует. Вам нужно будет создать свою собственную оболочку, если вы хотите использовать эту функциональность.   -  person Steve Guidi    schedule 19.04.2010
comment
Некромантия, но пришлось ответить на комментарий выше: Конечно не существует, поэтому и был задан вопрос. Если бы он существовал, пример работал бы как есть.   -  person EKW    schedule 15.03.2018


Ответы (5)


В дополнение к @Oded вы можете сделать метод универсальным также:

public T ConvertXml<T>(string xml)
{
    var serializer = new XmlSerializer(typeof(T));
    return (T)serializer.Deserialize(new StringReader(xml));
}

Таким образом, вам не нужно делать весь класс универсальным, и вы можете использовать его следующим образом:

var result = ConvertXml<MyObject>(source);
person Filip Ekberg    schedule 19.04.2010

Сделайте свой класс/метод сериализации универсальным:

public T LoadData<T>()
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    using (TextReader reader = new StreamReader(settingsFileName))
    {
        return (T)xmlSerializer.Deserialize(reader);
    }
}
person Oded    schedule 19.04.2010
comment
Это то, что я делаю в большинстве своих проектов. Но мне просто интересно, почему это не встроено в последние версии .NET Framework. - person Arseni Mourzenko; 20.04.2010

Простая универсальная оболочка:

public class GenericSerializer<T> : XmlSerializer
{
    public GenericSerializer(): base(typeof(T)) { }
}

Это сериализует ваш объект в папку bin/debug:

static void Main(string[] args)
{
   Person p = new Person { Name = "HelloWorld" };
   GenericSerializer<Person> ser = new GenericSerializer<Person>();
   ser.Serialize(new StreamWriter("person.xml"), p);
}
person neo112    schedule 17.03.2014

Попробуй это.

public class SerializeConfig<T> where T : class
{
    public static void Serialize(string path, T type)
    {
        var serializer = new XmlSerializer(type.GetType());
        using (var writer = new FileStream(path, FileMode.Create))
        {
            serializer.Serialize(writer, type);
        }
    }

    public static T DeSerialize(string path)
    {
        T type;
        var serializer = new XmlSerializer(typeof(T));
        using (var reader = XmlReader.Create(path))
        {
            type = serializer.Deserialize(reader) as T;
        }
        return type;
    }
}
person Hasan Javaid    schedule 12.05.2016

всегда работает для меня

  public static string ObjectToXmlSerialize<T>(T dataToSerialize)
    {
        try
        {
            var stringwriter = new System.IO.StringWriter();
            var serializer = new XmlSerializer(typeof(T));
            serializer.Serialize(stringwriter, dataToSerialize);
            return stringwriter.ToString();
        }
        catch (Exception ex)
        {
        }
        return null;
    }

и это для Deserialize:

  public static T XmlDeserializeToObject<T>(string xmlText)
    {
        try
        {
            var stringReader = new System.IO.StringReader(xmlText);
            var serializer = new XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(stringReader);
        }
        catch (Exception ex)
        {
        }
        return default(T);
    }
person tokenaizer    schedule 15.01.2018