【问题标题】:How Can I Get The Value of an Item in an Array via Reflection如何通过反射获取数组中项目的值
【发布时间】:2016-06-06 18:47:04
【问题描述】:

跳到问题的第三段。

背景:我正在创建一个 2D 宇宙飞船游戏,其中一个游戏机制是将电源分配给飞船的 7 个不同部分,以适应您当前所处的情况。有您可以随时切换到的预设,称为电源配置。我将电源配置存储在 3 个不同的数组中,如下所示:

int[] powerConfiguration1 = new int[7] {10,10,10,10,20,20,20};
int[] powerConfiguration2 = new int[7] {20,20,20,10,10,10,10};
int[] powerConfiguration3 = new int[7] {10,20,10,20,10,20,10};

当您切换配置时,它会调用一个方法来执行此操作。该方法进行一些计算以确定切换配置需要多长时间。但是,在播放器切换到三种配置中的任何一种的情况下,我不想制作 switch 语句并多次复制/粘贴代码,而是想使用 System.Reflections 中的 PropertyInfo 来选择我需要从中提取值的属性。

问题:问题是我不知道如何从数组中获取项目。这是我到目前为止所拥有的,我试图确定总共需要重新路由多少功率并将其全部添加到变量中。 0 是我决定存储屏蔽能量的配置中的索引。 powerToShields 是路由到屏蔽的当前电源。

void switchConfiguration(int number) {
PropertyInfo powerConfiguration = GetType().GetProperty("powerConfiguration" + number);
int powerToReroute = 0;
powerToReroute += Mathf.Abs(powerToShields - powerConfiguration[0]);

谁能解释我做错了什么和/或告诉我如何解决它?或者,有没有更好的方法来做到这一点?

编辑 1:这是用 C# (Unity) 编码的。

【问题讨论】:

  • 您发布的代码看起来像C#代码,请确认是
  • 是的,它是 C#。是否有一个选项我可以在某处打勾,告诉读者它是 C#,或者你是说我应该在帖子的某处说它是 C#?
  • 看起来你明白了,它现在被标记为 C#
  • 好吧,很酷。有什么见解,还是您只是想为其他人澄清一下?

标签: c# arrays unity5 propertyinfo


【解决方案1】:

旁观

我想我的第一个问题是为什么不将数组存储在列表中。那么,为什么不存储一个int[]列表,而不是powerConfiguration1、powerConfiguration2、powerConfiguration3,所以

List<int[]> powerConfigurationList = new List<int[]>;
powerConfigurationList.Add(new int[7] {10,10,10,10,20,20,20});
powerConfigurationList.Add(new int[7] {20,20,20,10,10,10,10});
powerConfigurationList.Add(new int[7] {10,20,10,20,10,20,10});

这样你就可以通过:

powerToReroute = (powerConfigurationList[number])[0]

回答您的问题

但是,假设有充分的理由您不能这样做,为了回答您的确切问题,请执行以下操作:

...
PropertyInfo powerConfiguration = GetType().GetProperty("powerConfiguration" + number); //this line is taken from your example above

//then you need to do something like the below
var value = (int[])powerConfiguration.GetValue(instanceThatHasTheProperty);
int powerToReroute = 0;
powerToReroute += Mathf.Abs(powerToShields - value[0]);

从你的代码 sn-p,我看到你有 GetType().GetProperty("powerConfiguration" + number);。我不确定您从哪个实际实例中获取该类型。所以你需要在我上面的 sn-p 中替换instanceThatHasTheProperty,无论你试图从中获取属性值的任何实例。

【讨论】:

  • 我试图做的是确定我需要从哪个数组中提取值,方法是使用字符串(“powerConfiguration”)和玩家选择的配置编号(编号)构造它的名称。因此,如果玩家希望切换到电源配置编号 2,那么“powerConfiguration”+ 编号将等于“powerConfiguration2”,我将使用包含属性名称的字符串来查找属性本身并访问它...我在我的其他一个项目中使用了几乎与此类似的代码,所以我认为它也可以在这里工作。
  • 但是,将数组存储在列表中听起来要简单得多。我会试试看,然后带着我的结果回到这个帖子。
  • 是的。所以上面给了你两个选择。答案的后半部分给出了一个解决方案,可以用您想要的设计来回答您的问题。
【解决方案2】:

对我来说立即显而易见的是,代码被不必要地混淆了,看起来非常像 X-Y 问题。使用锯齿状数组和反射似乎要完成面向对象编程的大量工作。我的建议是创建一个类来存储您的电源配置,将多个电源配置存储在一个列表中,然后从列表中选择配置。

电源配置示例类

public class PowerConfiguration
{
    public int ID { get; set; }

    public string Name { get; set; }

    public int Shields { get; set; }

    public int Weapons { get; set; }

    public int LifeSupport { get; set; }

    public int Propulsion { get; set; }
}

插入和访问您的电源配置

public class DoStuff
{
    public void LoadPowerConfiguration()
    {
        // Create a List to store configurations
        List<PowerConfiguration> allPowerConfigurations = new List<PowerConfiguration>();

        // Add some mock data to the list
        allPowerConfigurations.Add(new PowerConfiguration()
        {
            ID = 0,
            Name = "Balanced Combat",
            Shields = 30,
            Weapons =  30,
            LifeSupport = 20,
            Propulsion = 20
        });

        allPowerConfigurations.Add(new PowerConfiguration()
        {
            ID = 1,
            Name = "Offensive",
            Shields = 20,
            Weapons = 50,
            LifeSupport = 10,
            Propulsion = 20
        });

        // Figure out which ID you what (eg. from the user pressing '0')
        int selectedConfigurationID = 0;

        // Get the configuration from the list
        PowerConfiguration selectedConfiguration =
            allPowerConfigurations.FirstOrDefault(p => p.ID == selectedConfigurationID);

        // Now perform your operations against the PowerConfiguration object's properties
        int powerToShields = 100;
        int powerToReroute = 0;

        powerToReroute += Math.Abs(powerToShields - selectedConfiguration.Shields);
    }
}

【讨论】:

  • 谢谢你。我完全忘记了使用另一个类来存储相关变量组。我将这个想法融入了我的代码中。
猜你喜欢
  • 2019-04-19
  • 1970-01-01
  • 2011-11-06
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2018-09-11
  • 1970-01-01
相关资源
最近更新 更多