Получить int [] из GetValue - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь получить массив int из метода GetValue (this, null), но я получаю только System.Int32 [].Есть идеи?Я ожидаю получить в качестве выходных данных значение последствия2 (когда функция будет вызываться с textNum = 2), то есть [3,4,5], но я получаю только «System.Int32 []».Мне нужно получить значение во время выполнения, потому что приложение, которое я разрабатываю, представляет собой тестовую игру с потенциально более чем 500 из этих массивов.

using System.IO;
using UnityEngine;
using System;
using System.Reflection;
using System.Linq;

public class DialogueManager : MonoBehaviour
{
    //999 IS RETURN TO MENU
    //1000 IS CLOSE GAME
    public static DialogueManager instance = null;
    Dialogues dial;
    public string text1 { get; set; }
    public string choices1 { get; set; }
    public int[] consequences1 { get; set; }
    public string text2 { get; set; }
    public string choices2 { get; set; }
    public int[] consequences2 { get; set; }
    public string text3 { get; set; }
    public string choices3 { get; set; }
    public int[] consequences3 { get; set; }
    public string text4 { get; set; }
    public string choices4 { get; set; }
    public int[] consequences4 { get; set; }
    public string text5 { get; set; }
    public string choices5 { get; set; }
    public int[] consequences5 { get; set; }
    string fixedName;

    string[] choices;
    string text;
    string[] consequences;
    private void Awake()
    {
        if(instance == null)
        {
            instance = this;
        }
        dial = new Dialogues();
        StreamReader sR = new StreamReader(Application.dataPath + "/GameData/dialogues.json");
        string json = sR.ReadToEnd();
        dial = JsonUtility.FromJson<Dialogues>(json);
        text1 = dial.text1;
        choices1 = dial.choices1;
        consequences1 = dial.consequences1;
        text2 = dial.text2;
        choices2 = dial.choices2;
        consequences2 = dial.consequences2;
        text3 = dial.text3;
        choices3 = dial.choices3;
        consequences3 = dial.consequences3;
        text4 = dial.text4;
        choices4 = dial.choices4;
        consequences4 = dial.consequences4;
        text5 = dial.text5;
        choices5 = dial.choices5;
        consequences5 = dial.consequences5;
    }
    public string GetText(int currentText)
    {
        fixedName = "text" + currentText;
        string output = typeof(DialogueManager).GetProperty(fixedName).GetValue(this, null).ToString();
        Debug.Log(output);
        return output;
    }
    public string GetTextChoices(int textNum)
    {
        fixedName = "choices" + textNum;
        string output = typeof(DialogueManager).GetProperty(fixedName).GetValue(this, null).ToString();
        if (output == "System.String[]")
        {
            output = null;
        }
        return output;
    }
    public int[] GetChoicesConsequences(int textNum)
    {
        fixedName = "consequences" + textNum;
        int[] values = (int[])((dynamic)this).fixedName;
        return values;

    }
}

public class Dialogues
{
    public string text1;
    public string choices1;
    public int[] consequences1;
    public string text2;
    public string choices2;
    public int[] consequences2;
    public string text3;
    public string choices3;
    public int[] consequences3;
    public string text4;
    public string choices4;
    public int[] consequences4;
    public string text5;
    public string choices5;
    public int[] consequences5;
}

1 Ответ

0 голосов
/ 04 марта 2019

Вместо

int[] values = (int[]) typeof(DialogueManager).GetProperty(fixedName).GetValue(this, null);

вы можете попытаться использовать

int[] values = (int[]) ((dynamic) this).fixedName;

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


Или, еще лучше, переосмыслить, почему вам нужно определять имена свойств во время выполнения?Разве простой

if(textNum == 1) return this.consequences1; 
else if(textNum == 2) return this.consequences2;
// ...

не подойдет?


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

Я просто перечитал ваш вопрос.Ваш вопрос о том, что Console.WriteLine печатает System.Int32[], когда вы хотите, чтобы он печатал действительные значения массива?Если это так, вы можете использовать

foreach(int v in values) // where values is your int[]
{
    Console.WriteLine(v);
}

, что дает

1
2
3

, или вы можете использовать

Console.WriteLine("[" + String.Join(",", values) + "]");

, что дает

[1,2,3]


РЕДАКТИРОВАТЬ 2 Ниже я написал код, который, я думаю, выполняет вашу задачу.Основная логика происходит в методе GetPropertyValueSafe, который отвечает за проверку того, существует ли запрошенное свойство, и, если это так, получает значение свойства как указанный тип.

public class DialogueManager
{
    private static IReadOnlyCollection<PropertyInfo> AllProperties = typeof(DialogueManager).GetProperties();

    private T GetPropertyValueSafe<T>(string propertyName)
    {
        PropertyInfo thePropertyInfo = DialogueManager.AllProperties.SingleOrDefault(x => x.Name == propertyName);

        if (thePropertyInfo is null)
        {
            throw new InvalidOperationException($"Type {this.GetType()} has no property {propertyName}.");
        }

        return (T) thePropertyInfo.GetValue(this);
    }

    private string ArrayToString<T>(T[] array)
    {
        return String.Join(", ", array);
    }

    public string GetText(int currentText)
    {
        return this.GetPropertyValueSafe<string>("text" + currentText);
    }

    public string GetTextChoices(int textNum)
    {
        return this.GetPropertyValueSafe<string>("choices" + textNum);
    }

    public int[] GetChoicesConsequences(int textNum)
    {
        return this.GetPropertyValueSafe<int[]>("consequences" + textNum);
    }

    public string text1 { get; set; } = "Text 1";
    public string choices1 { get; set; } = "Choice 1";
    public int[] consequences1 { get; set; } = new int[] { 1, 2 };
    public string text2 { get; set; } = "Text 2";
    public string choices2 { get; set; } = "Choice 2";
    public int[] consequences2 { get; set; } = new int[] { 1, 2, 3 };

    public static void Main(string[] args)
    {
        DialogueManager d = new DialogueManager();

        Console.WriteLine(d.ArrayToString(d.GetChoicesConsequences(1)));
        Console.WriteLine(d.GetText(1));
        Console.WriteLine(d.GetTextChoices(1));
        Console.WriteLine(d.ArrayToString(d.GetChoicesConsequences(2)));
        Console.WriteLine(d.GetText(2));
        Console.WriteLine(d.GetTextChoices(2));
        Console.ReadLine();
    }
}

Код выше дает

> 1, 2
> Text 1
> Choice 1
> 1, 2, 3
> Text 2
> Choice 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...