Вывод класса сохраненных значений в список - PullRequest
6 голосов
/ 07 февраля 2012

Это загружает набор значений из файла XML и помещает их в класс для хранения. Я пытаюсь выяснить, как вывести значения в виде списка, чтобы я мог поместить их в список.

Я подумал, что будет простой способ, например метод .ToList (), или возможность иметь доступ к строкам в классе (нет общедоступного GetEnumerator). Мне удалось выяснить, что Foreach скрывает некоторые сложности, но не делает то, что я хочу.

Я искал в Интернете безрезультатно (возможно, не хватает правильной терминологии), к сожалению, я оставил свои справочники по C # на работе: /

Очень хотел бы указатель в правильном направлении, Спасибо.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;

namespace ThereIsOnlyRules
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        try
        {
            listBox1.Items.Clear();

            string path = "characterXML.xml";
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            System.Xml.XmlDocument CXML = new System.Xml.XmlDocument();

            CXML.Load(fs);

            //Get the number of elements 
            XmlNodeList elemList = CXML.GetElementsByTagName("unit");

            //foreach (var element in elemList)
            //{
            //    listBox1.Items.Add(element);
            //}

            for (int i = 0; i < elemList.Count; i++)
            {
                UnitAttributes attributes = new UnitAttributes();

                attributes.army = elemList[i].Attributes["army"].Value;
                attributes.category = elemList[i].Attributes["category"].Value;
                attributes.type = elemList[i].Attributes["type"].Value;
                attributes.composition = elemList[i].Attributes["composition"].Value;
                attributes.WS = elemList[i].Attributes["WS"].Value;
                attributes.BS = elemList[i].Attributes["BS"].Value;
                attributes.T = elemList[i].Attributes["T"].Value;
                attributes.W = elemList[i].Attributes["W"].Value;
                attributes.I = elemList[i].Attributes["I"].Value;
                attributes.A = elemList[i].Attributes["A"].Value;
                attributes.LD = elemList[i].Attributes["LD"].Value;
                attributes.save = elemList[i].Attributes["Save"].Value;
                attributes.armour = elemList[i].Attributes["armour"].Value;
                attributes.weapons = elemList[i].Attributes["weapons"].Value;
                attributes.specialrules = elemList[i].Attributes["specialrules"].Value;
                attributes.transport = elemList[i].Attributes["transport"].Value;
                attributes.options = elemList[i].Attributes["options"].Value;

                //foreach (string item in attributes)
                //{

                    //unit.Add(item);
                //}
                //listBox1.Items.AddRange(attributes)

            }  

            //Close the filestream
            fs.Close();
        }
        catch (Exception ex)
        {

        }
    }
}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ThereIsOnlyRules
{
class UnitAttributes
{
    public string army { get; set; }
    public string category { get; set; }
    public string type { get; set; }
    public string composition { get; set; }
    public string WS { get; set; }
    public string BS { get; set; }
    public string T { get; set; }
    public string W { get; set; }
    public string I { get; set; }
    public string A { get; set; }
    public string LD { get; set; }
    public string save { get; set; }
    public string armour { get; set; }
    public string weapons { get; set; }
    public string specialrules { get; set; }
    public string transport { get; set; }
    public string options { get; set; }
    }
}

<?xml version="1.0"?>
<config>
<unit
army="Tyranids"
category="Troops"
type="Infantry"
composition="10-30"
WS="3"
BS="3"
T="3"
W="1"
I="4"
A="1"
LD="6"
Save="6+"
armour="Chitin"
weapons="Claws and Teeth, Fleshborer"
specialrules="Instictive Behaviour - Lurk, Move Through Cover"
transport="If the brood consists of 20 models or less, it may take a Mycetic Spore."
options="Strangleweb, Spinefists, Spike rifle, Devourer, Adrenal Glands, Toxin Sacs"
>
Termagant Brood
</unit>
<unit
army="Tyranids"
category="Troops"
type="Infantry"
composition="10-30"
WS="3"
BS="3"
T="3"
W="1"
I="5"
A="2"
LD="6"
Save="6+"
armour="Chitin"
weapons="Scything Talons"
specialrules="Instictive Behaviour - Feed, Bounding Leap, Fleet, Move Through Cover"
transport="If the brood consists of 20 models or less, it may take a Mycetic Spore."
options="Adrenal Glands, Toxin Sacs"
>
Hormagaunt Brood
</unit>
</config>

Ответы [ 2 ]

3 голосов
/ 07 февраля 2012

Являются ли члены вашего класса полями или свойствами? В любом случае, небольшое размышление и Linq должны позволить вам перечислять элементы данных вашего класса после того, как вы скопировали их экземпляр из своего XML-файла.

var fieldDictionary = 
   (from f in typeof(UnitAttributes).GetFields()
    select new {Name = f.Name, Value = (string)(f.GetValue(attributes))})
   .ToDictionary(x=>x.Name, x=>x.Value);

fieldDictionary теперь является Dictionary<string, string> (то есть IEnumerable<KeyValuePair<string, string>>), который должен подходить для загрузки в ListBox.

Имейте в виду; отражение медленное. Для вас было бы гораздо предпочтительнее изменить или расширить свой класс UnitAttributes для реализации IEnumerable (возможно, из Tuple, может быть, из KeyValuePair). Это также позволит вам перечислять свойства экземпляра класса именно в том порядке, в каком вы хотите, а не в порядке, в котором они определены, или с помощью некоторых других данных FieldInfo / PropertyInfo, таких как имя поля.

Также следует помнить, что поле не является свойством, и наоборот. Если у вас есть сочетание свойств и открытых полей в вашем классе, я НАСТОЯТЕЛЬНО рекомендую стандартизировать один или другой; в противном случае вам придется отражать ОБА и список свойств и список полей, используя два из приведенных выше операторов Linq (по стоимости примерно в два раза больше времени выполнения), и не будет никакой вероятности того, что они окажутся в каких-либо пользовательских заказ.

2 голосов
/ 07 февраля 2012

Вы сэкономите много времени и усилий, если будете использовать обычный сериализатор , такой как XmlSerializer , для обработки ваших объектов в / из строк.Вам не нужно писать этот тип кода с нуля.

...