从GetValue获取一个int []

时间:2019-03-04 10:22:24

标签: c# arrays unity3d

我正在尝试从方法GetValue(this,null)获取一个int数组,但是我仅获取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 :(得分:0)

代替

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