如何获取存储在数组中的类中的值?

Posted

技术标签:

【中文标题】如何获取存储在数组中的类中的值?【英文标题】:How do I get a value within a class stored within an array? 【发布时间】:2021-02-22 00:47:57 【问题描述】:

我正在 Unity 中制作 C# 脚本。我的意图是创建一个类Scenario,创建代表不同场景的类,然后将其存储在数组scenarioListAll中。

代码的一个(简化)版本如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OverallManager2 : MonoBehaviour


public static object[] scenarioListAll = new object[40];

public class Scenario

    public string scenarioDesc;
    public bool surprise;     // The 'surprise' bool I want to reference is defined here
    public string surpriseType;
    public int[] leftOption;
    public int[] rightOption;
    public int scenarioNumber;

    public Scenario(string st, bool sp, int[] l, int[] r, int n)
    
        scenarioDesc = st;
        surprise = sp;
        leftOption = l;
        rightOption = r;
        scenarioNumber = n;
    

    // I haven't used this, but I'm not sure if this matters so I'm including this too
    public Scenario(string st, bool sp, string spt, int[] l, int[] r, int n)
    
        scenarioDesc = st;
        surprise = sp;
        surpriseType = spt;
        leftOption = l;
        rightOption = r;
        scenarioNumber = n;
    



public static int[] getArray(int a, int b, int c, int d, int e, int f)

    int[] arr = new int[6] a, b, c, d, e, f;
    return arr;



// Storing scenarios, am looking for the bool (2nd position)
public Scenario s1 = new Scenario("Test1", false, getArray(1, 1, 1, 1, 1, 1), getArray(1, 1, 1, 1, 1, 1), 1);
public Scenario s2 = new Scenario("Test2", true, getArray(1, 1, 1, 1, 1, 1), getArray(1, 1, 1, 1, 1, 1), 2);
public Scenario s3 = new Scenario("Test3", false, getArray(1, 1, 1, 1, 1, 1), getArray(1, 1, 1, 1, 1, 1), 3);

    void Awake()
    
        // Store scenarios in object array
        scenarioListAll[0] = s1;
        scenarioListAll[1] = s2;
        scenarioListAll[2] = s3;

        for(int i = 0; i < 40; i++)
        
            object temp = scenarioListAll[i];     // Trying to extract the object stored in the array in a temp object
            bool surpriseCheck = temp.surprise;     // I am having problems with this line
            if(surpriseCheck == true)
            
                // Do something
            
        
    
// Ignoring start and update since they're irrelevant in this context

我想做的是检查新定义的场景(例如s1)中的surprise元素是否为真。为此,我计划提取存储在数组scenarioListAll 中的场景,然后从那里提取surprise 组件。但是,我不知道如何执行此操作(例如,在上面显示的代码中,它返回编译器错误 CS1061)。

我认为我也找不到任何关于此的文档,但我可能没有理解某些内容。我是自学,所以请多多包涵我的知识/演示文稿。

感谢您的宝贵时间。非常感谢您的帮助。

【问题讨论】:

object 没有 .surprise 属性。也许您应该将数组定义为public static Scenario[] scenarioListAlltempScenario temp = scenarioListAll[i];?为什么在这些情况下使用object 对不起@Rufus L,我对此不好。我没有意识到我可以直接为Scenario 使用数组。不过问题已经解决了,感谢您的意见。 【参考方案1】:

您遇到了编译问题,因为 c# 编译器不知道 temp 是一个场景,因为您将它声明为“对象”。如果您想遍历场景并检查它们是否令人惊讶,您可以使用以下内容:

 foreach(Scenario temp in scenarioListAll)
 
        bool surpriseCheck = temp.surprise;     
        if(surpriseCheck == true)
        
            // Do something
        
 

通过对迭代进行更多控制来完成相同任务的另一种方法是:

 for(int i = 0; i < scenarioListAll.Length; i++)
 
        Scenario temp = scenarioListAll[i];
        bool surpriseCheck = temp.surprise;     
        if(surpriseCheck == true)
        
            // Do something
        
 

第一个版本的好处是您不必担心超出数组的边界。正如 Mike 在下面添加的,您还可以使用 var 让编译器为您填写类型。

【讨论】:

foreach 与语法糖相差甚远。他们是两个非常不同的东西。 for 语句定义初始化器、条件和迭代器部分,并在条件为真时执行代码块。另一方面,foreach 为实现 System.Collections.IEnumerable 或 System.Collections.Generic.IEnumerable 接口的类型实例中的每个元素执行代码块。 @Immersive 这实际上是不正确的,而是会抛出 InvalidCastExceptionforeach 只是 IEnumerable 处理的快捷方式。 @imsmn 嗯,看起来是这样。我不确定我从哪里得到这个想法......:/ 我更新了帖子,因为我认为它是语法糖是不正确的。当我在两者之间来回走动时,我想我混淆了 java 和 .net。【参考方案2】:

有时让编译器为我们确定变量的类型是最容易的。

在您的情况下,您已指定变量temp 的类型为object。现在,这很好,但是 Scenario 派生自 object,而 object 是 .Net 环境中的最低级别的类,而不是 Scenario

var 关键字并不意味着声明的类型是“变量”类型,而是告诉编译器根据您正在执行的操作“填写”正确的类型。因此,要在您的情况下将其付诸实践,您可以这样做:

    for( var i = 0; i < 40; i++ )                   // notice the use of var here as well
    
        var scenario = scenarioListAll[i];          // renamed temp to scenario
        // var surpriseCheck = scenario .surprise;  // var used but line not required
        if( scenario.surprise )
        
            // Do something
        
    

我在那里过分证明了编译器对var 关键字非常满意,几乎可以将数据类型指定为变量的类型。当您尝试强制转换类型时,显然不是,有时您想要指定您尝试实例化的确切类型。

在您的情况下,您的下一个问题将是您已将数组定义为具有 40 个 object 元素,但您只实例化了 3 个 Scenario 元素(这是有效的,但可能不是您所需要的想要整体)。因此,就目前而言,您的代码将出现 NullReference 错误。只需稍作修改,您就可以避免这种情况,因此您修改后的代码可能看起来像这样,包括一些类型检查:

for( var i = 0; i < scenarioListAll.Length; i++ )

    // First, check to see if the object in the array cell is a Scenario.
    // If the item in the cell is a Scenario, check to see if surprise is set.
    if ( scenarioListAll[i] is Scenario scenario && scenario.surprise )
    
        // Do something
    

有关is 关键字的更多信息,请查看Microsoft Docs here。

【讨论】:

以上是关于如何获取存储在数组中的类中的值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在从 Wowza 中的 ModuleBase 派生的类中获取流的名称

利用反射机制自动获取某个类中的属性,以及获取和设置每个属性对应的值

如何在jsp页面直接获取常量类中的常量

如何从 extjs 存储中获取 JSON 数组中的属性值?

从脚本中的类中获取值

如何使用jquery获取以值开头的类并将事件添加到每个类中的复选框[关闭]