Как перебрать поля структуры? - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть простая структура, которая выглядит следующим образом:

public struct GridNeighbours
{
    public static Vector2Int North = new Vector2Int(0, 1);
    public static Vector2Int South = new Vector2Int(0, -1);
    public static Vector2Int East = new Vector2Int(1, 0);
    public static Vector2Int West = new Vector2Int(-1, 0);
}

Есть ли способ как-то "итерировать" через каждое из этих полей с помощью цикла for? Структуры случайно индексируют свои поля или что-то еще? Это сделало бы мой код намного чище, если бы это было возможно, но я не уверен, как сделать его итеративным.

Редактировать : из-за того, что это используется в игре на горячем пути, есть ли способ переписать это, чтобы я мог избежать отражения?

Это не дубликат, так как мне нужен альтернативный подход к избегать отражения.

Ответы [ 4 ]

0 голосов
/ 06 сентября 2018
public struct GridNeighbours {

    public enum Cardinal { North, East, South, West }

    public static Vector2Int[] Neighbours = { new Vector2Int(0, 1), new Vector2Int(1, 0), new Vector2Int(0, -1), new Vector2Int(-1, 0) };

    public Vector2Int this[Cardinal dirn] {
        get { return this[(int)dirn]; }
        set { this[(int)dirn] = value; }
    }

    public Vector2Int this[int dirn] {
        get { return Neighbours[dirn]; }
        set { Neighbours[dirn] = value; }
    }
}

Пример использования:

var cell = new GridNeighbours();
var NorthNeighbour = cell[Cardinal.North];
Assert(cell[Cardinal.South] == cell[2]); // This is true!

===

В качестве альтернативы, если вы хотите "прямые" свойства:

public struct GridNeighbours {
    public enum Cardinal { North, East, South, West }

    public static Vector2Int[] Neighbours = { new Vector2Int(0, 1), new Vector2Int(1, 0), new Vector2Int(0, -1), new Vector2Int(-1, 0) };

    public static Vector2Int North { get { return Neighbours[0]; } set { Neighbours[0] = value; } }
    public static Vector2Int East { get { return Neighbours[1]; } set { Neighbours[1] = value; } }
    public static Vector2Int South { get { return Neighbours[2]; } set { Neighbours[2] = value; } }
    public static Vector2Int West { get { return Neighbours[3]; } set { Neighbours[3] = value; } }
}
0 голосов
/ 04 сентября 2018

Если вы имеете в виду, что возможные значения в структуре не будут известны во время компиляции, тогда вы можете попробовать использовать Reflection. Более конкретно, используя Type.GetFields() или Type.GetProperties().

Пример:

Type structType = typeof(GridNeighbours); 
FieldInfo[] fields = structType.GetFields(); 
Foreach(FieldInfo field in fields) 
{
    //Do something
}

Но учитывая тот факт, что всегда будет четыре направления, почему простой GridNeighboursInstance.North не является для вас предпочтением.

0 голосов
/ 04 сентября 2018

Если вы не хотите использовать динамический способ, поэтому я могу предложить вам использовать статический способ! Когда у вас есть только эти четыре члена, и вы хотите перебрать их, вам нужно реализовать метод AsEnumerable внутри вашего struct что-то вроде этого:

public static IEnumerable<Vector2Int> AsEnumerable()
{
    for (var i = 0; i < 4; i++)
    {
        switch (i)
        {
            case 1:
                yield return North;
                break;
            case 2:
                yield return South;
                break;
            case 3:
                yield return East;
                break;
            case 4:
                yield return West;
                break;
        }
    }
}

Я думаю, что есть и лучший способ, но HTH;).

0 голосов
/ 04 сентября 2018

Не используя отражения, я не думаю, что вы можете сделать это, если у вас есть подпись.

То, что вы могли бы сделать, это настроить индексатор на структуру, которая позволила бы вам зацикливаться.

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