C# - Как к xml десериализовывают сам объект?

Я не знаю, сможете ли вы сделать это с помощью find, но альтернативным решением было бы создать сценарий оболочки и запустить его с помощью find.

lastline.sh:

echo $(tail -1 $1),$1

Сделать сценарий исполняемым

chmod +x lastline.sh

Использовать find:

find . -name "*.txt" -exec ./lastline.sh {} \;
8
задан Eric Schoonover 4 July 2009 в 03:48
поделиться

5 ответов

Это будет работать, если ваш тип Options является структурой, так как вы можете изменить саму структуру.

Если Options - это класс (ссылочный тип), вы не можете назначить текущий экземпляр ссылочного типа в этом экземпляре. Предлагая вам написать вспомогательный класс и поместить туда свои методы Read и Save, как это

     public class XmlSerializerHelper<T>
    {
        public Type _type;

        public XmlSerializerHelper()
        {
            _type = typeof(T);
        }


        public void Save(string path, object obj)
        {
            using (TextWriter textWriter = new StreamWriter(path))
            {
                XmlSerializer serializer = new XmlSerializer(_type);
                serializer.Serialize(textWriter, obj);
            }

        }

        public T Read(string path)
        {
            T result;
            using (TextReader textReader = new StreamReader(path))
            {
                XmlSerializer deserializer = new XmlSerializer(_type);
                result = (T)deserializer.Deserialize(textReader);
            }
            return result;

        }
    }

А затем использовать его у вызывающего, чтобы читать и сохранять объекты, вместо того, чтобы пробовать это из класса.

//In the caller

var helper=new XmlSerializerHelper<Options>();
var obj=new Options();

//Write and read
helper.Save("yourpath",obj);
obj=helper.Read("yourpath");

И поместите XmlSerializerHelper в пространстве имен Util, он может использоваться повторно и будет работать с любым типом.

11
ответ дан 5 December 2019 в 04:49
поделиться

Создайте свой метод .Read () как статическую функцию, которая возвращает прочитанный объект:

public static Options Read(string path)
{
    XmlSerializer deserializer = new XmlSerializer(typeof(Options));
    using (TextReader textReader = new StreamReader(path))
    {
        return (Options)deserializer.Deserialize(textReader);
    }
}

Затем измените свой вызывающий код так, а не что-то вроде этого:

Options myOptions = new Options();
myOptions.Read(@"C:\Options.xml");

Вы делаете что-то вроде этого:

Options myOptions = Options.Read(@"C:\Options.xml");

Хорошая разница в том, что невозможно иметь объект Options, за которым не было бы каких-то данных.

19
ответ дан 5 December 2019 в 04:49
поделиться

Объект не может десериализовать себя по определению: он уже существует, и десериализация создает новый экземпляр типа.

Иногда имеет смысл создать новый пустой экземпляр класса, а затем заполнить его с информацией, полученной из XML. Экземпляр также может быть «почти пустым». Вы можете сделать это, например, для загрузки пользовательских предпочтений или вообще, чтобы вернуть экземпляр в прежнее состояние. «Пустое» или «почти пустое» состояние экземпляра было бы допустимым состоянием для класса: он просто не знал бы, в каком состоянии он находился до того, как он был сохранен.


Кроме того, Я рекомендую вам выработать привычку реализовывать блоки «using»:

public void Save()
{
    XmlSerializer serializer = new XmlSerializer(typeof(Options));
    using (TextWriter textWriter = new StreamWriter(@"C:\Options.xml"))
    {
        serializer.Serialize(textWriter, this);
        // no longer needed: textWriter.Close();
    }
}

public void Read()
{
    XmlSerializer deserializer = new XmlSerializer(typeof(Options));
    using (TextReader textReader = new StreamReader(@"C:\Options.xml"))
    {
        // no longer needed: textReader.Close();
    }
}

Это гарантирует, что TextReaders будут удалены, даже если будет сгенерировано исключение. Вот почему вызовы Close больше не нужны.

5
ответ дан 5 December 2019 в 04:49
поделиться

См. Метод XmlSerializer.Deserialize : Вы можете создать статический метод, подобный следующему:

    public static Options DeserializeFromFile(string filename) {    
       // Create an instance of the XmlSerializer specifying type and namespace.
       XmlSerializer serializer = new XmlSerializer(typeof(Options));

       // A FileStream is needed to read the XML document.
       using (FileStream fs = new FileStream(filename, FileMode.Open)) {
           XmlReader reader = new XmlTextReader(fs);
           return (Options) serializer.Deserialize(reader);
       } // using
    }

Вышеупомянутое можно вызвать как:

 Options foo = Options.DeserializeFromFile(@"C:\Options.xml");
0
ответ дан 5 December 2019 в 04:49
поделиться

Я выбрал такой подход (в vb)

    Public Class SerialisableClass

    Public Sub SaveToXML(ByVal outputFilename As String)

        Dim xmls = New System.Xml.Serialization.XmlSerializer(Me.GetType)
        Using sw = New IO.StreamWriter(outputFilename)
            xmls.Serialize(sw, Me)
        End Using

    End Sub

    Private tempState As Object = Me
    Public Sub ReadFromXML(ByVal inputFilename As String)

        Dim xmls = New System.Xml.Serialization.XmlSerializer(Me.GetType)

        Using sr As New IO.StreamReader(inputFilename)
            tempState = xmls.Deserialize(sr)
        End Using

        For Each pi In tempState.GetType.GetProperties()

            Dim name = pi.Name

            Dim realProp = (From p In Me.GetType.GetProperties
                            Where p.Name = name And p.MemberType = Reflection.MemberTypes.Property).Take(1)(0)

            realProp.SetValue(Me, pi.GetValue(tempState, Nothing), Nothing)

        Next

    End Sub

End Class

Я могу просто использовать что-то вроде этого:

Public Class ClientSettings

    Inherits SerialisableClass

    Public Property ZipExePath As String
    Public Property DownloadPath As String
    Public Property UpdateInstallPath As String

End Class

и вызывать это так:

Dim cs As New ClientSettings
cs.ReadFromXML("c:\myXMLfile.xml")

или даже лучше (если я добавлю необходимый конструктор):

Dim cs as New ClientSettings("c:\myXMLFile.xml")

Мне кажется, это хорошо и чисто и хорошо работает в моей ситуации.

Будьте здоровы

1
ответ дан 5 December 2019 в 04:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: