如何遍历结构的字段?

时间:2018-09-04 03:32:49

标签: c# loops unity3d struct

我有一个简单的结构,如下所示:

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 :(得分:2)

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; } }
}

答案 1 :(得分:0)

如果不使用反射,考虑到那里的签名,我认为您无法做到这一点。

可以要做的是在结构上设置一个索引器,以使您可以循环。

答案 2 :(得分:0)

如果您表示在编译时不知道结构中的可能值,则可以尝试使用Reflection。更具体地说,使用Type.GetFields()Type.GetProperties()

示例:

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

但是请记住,总会有四个方向,为什么简单的GridNeighboursInstance.North并不是您的偏爱。

答案 3 :(得分:0)

如果您不想使用动态方式,那么我建议您使用静态方式!当只有四个成员并且要遍历它们时,您需要在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;)。