#c# #arrays #class #unity3d
#c# #массивы #класс #unity3d
Вопрос:
Я создаю скрипт на C # в Unity. Я намереваюсь создать класс 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
}
Что я хотел бы сделать, так это проверить, является ли surprise
элемент в недавно определенном сценарии (например s1
) истинным. Для этого я планировал извлечь сценарий, хранящийся в массиве scenarioListAll
, а затем извлечь surprise
оттуда компонент. Однако я не мог понять, как это сделать (например, в коде, показанном выше, он возвращает ошибку компилятора CS1061).
Я не думаю, что мне удалось найти какую-либо документацию по этому вопросу, но, возможно, я чего-то не понял. Я учусь самостоятельно, поэтому, пожалуйста, примите во внимание мои плохие знания / презентацию.
Спасибо за ваше время. Ваша помощь очень ценится.
Комментарии:
1.
object
не имеет.surprise
свойства. Возможно, вам следует определить массив какpublic static Scenario[] scenarioListAll
иtemp
какScenario temp = scenarioListAll[i];
? Почему вы используетеobject
в этих случаях?2. Извините @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
}
}
Преимущество первой версии в том, что вам не нужно беспокоиться о превышении границ массива. Как добавил Майк ниже, вы также можете использовать var, чтобы компилятор заполнял тип для вас.
Комментарии:
1.
foreach
это ДАЛЕКО от синтаксического сахара. Это две ОЧЕНЬ разные вещи.for
Оператор определяет разделы инициализатора, условия и итератора и выполняет блок кода, пока условие истинно.foreach
с другой стороны, выполняет блок кода для каждого элемента в экземпляре типа, который реализует Систему. Коллекции. IEnumerable или System. Коллекции. Общий. Интерфейс IEnumerable<T> .2. @Immersive На самом деле это неверно,
InvalidCastException
вместо этого будет выбрано a .foreach
это просто ярлык дляIEnumerable
обработки.3. @imsmn Хм, так кажется. Я не уверен, откуда я взял эту идею… :/
4. Я обновил сообщение, потому что я был неправ в том, что это синтаксический сахар. Я думаю, что я путаю java и .net, когда я переключаюсь между ними.
Ответ №2:
Иногда проще всего позволить компилятору определять тип переменной для нас.
В вашем случае вы указали, что переменная temp
будет иметь тип object
. Теперь это нормально, но в то время как a Scenario
является производным от object
, и object является классом самого низкого уровня в .Сетевая среда, и не является 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 amp;amp; scenario.surprise )
{
// Do something
}
}
для получения дополнительной информации о is
ключевом слове ознакомьтесь с документами Microsoft здесь .