C# Установите переменную, используя строку с именем переменной внутри

* Перешел на серализацию.

Резюме: у меня есть все переменные, предопределенные как null / 0. Я хочу установить их, используя данные из XML-документа. Документ содержит те же имена, что и переменные. Я не хочу использовать кучу других if, поэтому я пытаюсь сделать это на основе имен, которые я извлекаю из XML-документа.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Xml;
using System.IO;

public class ShipAttributes
{
    // Model Information
    string name;
    string modelName;
    string firingPosition;
    string cameraPosition;
    string cargoPosition;
    Vector3 cameraDistance;

    // Rotation
    float yawSpeed;
    float pitchSpeed;
    float rollSpeed;

    // Speed
    float maxSpeed;
    float cruiseSpeed;
    float drag;
    float maxAcceleration;
    float maxDeceleration;

    // Physics Properties
    float mass;

    // Collection Capacity
    float cargoSpace;

    // Combat [Defense]
    float structureHealth;
    float armorHealth;
    float shieldHealth;
    float shieldRadius;

    // Combat [Assault]
    float missileRechargeTime;
    float fireRate; 

    // Currency Related
    float cost;
    float repairMultiplier;

void PopulateShipList()
{
    if (shipList != null)
        return;

    string filepath = Application.dataPath + "/Resources/shipsdata.xml";

    XmlRootAttribute xml_Root = new XmlRootAttribute();
    xml_Root.ElementName = "SHIPS";
    xml_Root.IsNullable = true;
    //using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) 
    //{
        StringReader stringReader = new StringReader(filepath);
        stringReader.Read();
        XmlReader xRdr = XmlReader.Create(stringReader);
        XmlSerializer xml_s = new XmlSerializer(typeof(List<ShipAttributes>), xml_Root);
        shipList= (List<ShipAttributes>)xml_s.Deserialize(xRdr);
    //}
}
public ShipAttributes LoadShip(string inName)
{
    PopulateShipList();
    foreach (ShipAttributes att in shipList)
    {
        if (att.name == inName)
        {
            att.shipList = shipList;
            return att;
        }
    }

    return null;
}

* Примечание. Переменные в файлах XML имеют тот же формат и имя, что и переменные в классе. maxSpeed ​​в классе - это maxSpeed ​​в файле XML.

Мой XML выглядит так -

<?xml version="1.0" encoding="UTF-8 without BOM" ?>

     <SHIPS>
        <SHIP>
            <name>Default</name>
            <id>0</id>
            <modelName>Feisar_Ship</modelName>
            <firingPosition>null</firingPosition>
            <cameraPosition>null</cameraPosition>
            <cargoPosition>null</cargoPosition>
            <cameraDistance>null</cameraDistance>
            <yawSpeed>2000.0</yawSpeed>
            <pitchSpeed>3000.0</pitchSpeed>
            <rollSpeed>10000.15</rollSpeed>
            <maxSpeed>200000.0</maxSpeed>
            <cruiseSpeed>100000.0</cruiseSpeed>
            <drag>0.0</drag>
            <maxAcceleration>null</maxAcceleration>
            <maxDeceleration>null</maxDeceleration>
            <mass>5000.0</mass>
            <cargoSpace>150.0</cargoSpace>
            <structureHealth>100.0</structureHealth>
            <armorHealth>25.0</armorHealth>
            <shieldHealth>25.0</shieldHealth>
            <shieldRadius>30.0</shieldRadius>
            <missileRechargeTime>2.0</missileRechargeTime>
            <fireRate>0.5f</fireRate>
            <cost>0</cost>
            <repairMultiplier>1.0</repairMultiplier>
        </SHIP>   
     </SHIPS

>

Да, да, я знаю... Фейсар! Просто держатели пока из турбоскипей.

2 ответа

Решение

Создайте класс для хранения значений, которые вы читаете, и используйте сериализацию XML.

Microsoft Tutorial

Tech Pro Tutorial

MSDN: XmlSerializer

РЕДАКТИРОВАТЬ:

Если XML-файл точно такой же, как и код класса, который вы опубликовали, следующее должно позволить вам получить класс ShipAttributes:

ShipAttributes attributes = null;
string filepath = "/path/to/xml";

using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) {
    var xml_s = new XmlSerializer(typeof(ShipAttributes));

    attributes = (ShipAttributes)xml_s.Deserialize(stream);
}

Редактировать 2: несколько кораблей

В своем комментарии вы сказали, что файл содержит несколько ShipAttribute описания. Способ обработки такой же, как и выше, но десериализация файла в тип List<ShipAttribute> следующее:

List<ShipAttributes> ships = null;
string filepath = "/path/to/xml";

using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) {
    var xml_s = new XmlSerializer(typeof(List<ShipAttributes>));

    ships= (List<ShipAttributes>)xml_s.Deserialize(stream);
}

Как только вы это сделаете, у вас есть все корабли в памяти и вы можете выбрать тот из списка, который вам нужен, используя Linq и т. Д.

ПРИНИМАЯ ВАС XML ФАЙЛ

<?xml version="1.0" encoding="utf-8"?>
<Variables>      
    <VariableName1>1</VariableName1>
    <VariableName2>test</VariableName2>
    <VariableName3>test2</VariableName3>    
</Variables>



var data = XDocument.Load("YourXML.xml");
var xmldata = from x in data.Descendants("Variables")                        
                        select x;

notes.Select(_BuildPropertyFromElement);



private Yourclassname _BuildNoteFromElement(XElement element)
    {
      var type = typeof(**Yourclassname**);
      var Details = new Yourclassname();

      foreach (var propInfo in type.GetProperties())
      {
         var rawValue = element.Element(propInfo.Name).Value;
         var convertedValue = propInfo.PropertyType == typeof(DateTime) ?         (object)Convert.ToDateTime(rawValue) : rawValue;
            propInfo.SetValue(Details , convertedValue, null);
                }

                return Details ;
            }

YOURCLASSNAME - это имя класса, который будет иметь все свойства, которые вы хотите установить

Другие вопросы по тегам