Добавление нового столбца в существующий список - PullRequest
0 голосов
/ 01 октября 2019

У меня есть класс с полями - Id, name, company и еще 29 полей.

public class Employee
{
  [XmlAttribute("textbox1")]
  public int Id { get; set; }
  [XmlAttribute("textbox11")]
  public string Name { get; set; }
  [XmlAttribute("textbox21")]
  public string Company { get; set; }
  [XmlAttribute("textbox22")]
  public bool Val1 { get; set; }
  [XmlAttribute("textbox23")]
  public bool Val2 { get; set; }
  public bool TestSomething{get;set;}
}


public class ParseData()
{
   List<Employee> employee = new List<Employee>();
   XmlSerialiser serializer = new XmlSerializer();
   using(FileStream stream = new FileStream("test.xml", FileMode.Open))
   {
       employees = (Employee)serializer.Deserialize(stream);
   }

  //Todo: Add the new calculated value TestSomething

}

Я десериализирую значения из данных XML (в которых работает около 100 сотрудников).

Теперь у меня есть новое поле «TestSomething», которое не десериализовано, но будет результатом десериализованного значения, как показано ниже. Есть ли способ добавить расчетные значения для существующих сотрудников списка?

foreach(var i in employees)
{
  employee.TestSomething = (Val1 == true) ? Val1 : Val2;
}

Любое предложение по этому вопросу будет оценено.

1 Ответ

0 голосов
/ 01 октября 2019

Фрагменты кода ниже представляют собой методы расширения, которые я использую для сериализации и десериализации строк XML. Обратите внимание, что их нужно поместить в статический класс и использовать в классе для использования.

    /// <summary>
    /// Serializes the object to xml string.
    /// </summary>
    /// <returns>xml serialization.</returns>
    public static string SerializeToXml<T>(this T instance)
        where T : class, new()
    {
        string result;

        var format = new XmlSerializer(typeof(T));
        using (var strmr = new StringWriter())
        {
            format.Serialize(strmr, instance);
            result = strmr.ToString();
        }

        return result;
    }

    /// <summary>
    /// Deserializes xml serialized objects.
    /// </summary>
    /// <param name="xmlDocument">serialized string.</param>
    /// <param name="result">out parameter.</param>
    /// <returns>Instance object.</returns>
    public static bool TryParseXml<T>(this string xmlDocument, out T result)
        where T : class, new()
    {
        result = null;

        if (string.IsNullOrWhiteSpace(xmlDocument))
        {
            return false;
        }

        try
        {
            using (TextReader str = new StringReader(xmlDocument))
            {
                var format = new XmlSerializer(typeof(T));
                XmlReader xmlReader = XmlReader.Create(str);
                if (format.CanDeserialize(xmlReader))
                {
                    result = format.Deserialize(xmlReader) as T;
                }
            }
        }
        catch (InvalidOperationException)
        {
            return false;
        }

        return !(result is null);
    }

На практике у вас будет класс некоторого типа, который имеет свойства, которые вы хотите сохранить на диске илибаза данных и т. д. Допустим, у меня есть класс:

public class MyPoint
{
    public double X { get; set;}
    public double Y { get; set;}
}

Если бы я хотел сохранить список MyPoint без особых усилий, я мог бы сериализовать класс напрямую, используя метод SerializeToXml, описанный выше.

var myPoints = new List<MyPoint>{new MyPoint{ X= 1, Y = 2}, new MyPoint{X = 3, Y = 4}};

var xmlString = myPoints.SerializeToXml();

Все хорошо и прекрасно, моя информация где-то сохраняется в виде xml. Но затем мой босс говорит: «Черт, извините за это, но теперь нам нужно значение Z, которое вычисляется из X и Y каждого с использованием Z = X * X + Y * Y

Добавление свойств в сериализованный класс непроблема (удаление свойств - это! Сериализатор попытается присвоить значение несуществующему свойству и выдаст исключение.) . Но в этом случае нам не нужно беспокоиться. Я иду к исходному классу MyPoint и добавляю Z.

public class MyPoint
{
    public double X { get; set;}
    public double Y { get; set;}
    public double Z { get; set;}  // <---- Here
}

Теперь, когда я проанализирую xml, я получу классы с новым свойством. Используя TryParseXml, я получаю список точек.

// assume I have a string already from the xml document to use.

List<MyPoint> points = null;

if(serializedPoints.TryParse(out points))
{
    foreach(var point in points)
    {
        point.Z = X * X + Y * Y;
    }
}


var serializedPointsWithZ = points.SerializeToXml();

Теперь serializedPointsWithZ - это просто строка, которую можно записать в файл и т. Д.

...