结构:字段必须完全分配编译器错误

时间:2013-04-14 15:43:07

标签: c# constructor struct

我已经声明了以下结构:

struct StartPositions
{
    public Vector2 pacman;
    public Vector2[] ghosts;

    // Constructor accepts a Vector2, and an array of Vector2's.
    public StartPositions(Vector2 pacmanPosIn, Vector2[] ghostsPosIn)
    {
        pacman = pacmanPosIn;
        for(int a=0;a<ghostsPosIn.Length;a++)
        {
            ghosts[a] = ghostsPosIn[a];
        }
    }
}

但是我收到编译错误,说必须完全分配ghosts字段。我想要做的是在创建一个StartPositions对象时传入一个Vector2和一个Vector2数组 - 制作该数组的副本。

我该如何正确地做到这一点?

4 个答案:

答案 0 :(得分:2)

您没有初始化ghosts数组。您需要添加对new的调用。

public StartPositions(Vector2 pacmanPosIn, Vector2[] ghostsPosIn)
{
    pacman = pacmanPosIn;
    ghosts = new Vector2[ghostsPosIn.Length];
    ....
}

您可以通过调用for替换Array.Copy()循环来简化代码。

Array.Copy(ghostsPosIn, ghosts, ghosts.Length);

答案 1 :(得分:1)

您必须先初始化ghosts数组:

struct StartPositions
{
    public Vector2 pacman;
    public Vector2[] ghosts;

    // Constructor accepts a Vector2, and an array of Vector2's.
    public StartPositions(Vector2 pacmanPosIn, Vector2[] ghostsPosIn)
    {
        pacman = pacmanPosIn;
        ghosts = new Vector2[ghostsPosIn.Length];
        for(int a=0;a<ghostsPosIn.Length;a++)
        {
            ghosts[a] = ghostsPosIn[a];
        }
    }
}

答案 2 :(得分:0)

您没有初始化ghosts数组。

public StartPositions(Vector2 pacmanPosIn, Vector2[] ghostsPosIn)
{
    ...
    ghosts = new Vector2[ghostsPosIn.Length];
    ...
}

来自C# Language Specification;

  

实际的数组实例是在运行时使用动态创建的   运营商。新操作指定新数组的长度   实例,然后在实例的生命周期内修复。

答案 3 :(得分:0)

.net中一个恼人的怪癖是,除非使用“不安全”代码,否则值类型数组的概念不存在。所示的结构包含“pacman”的位置和对保持鬼影位置的可变数组的引用。这是一个邪恶的组合,因为结构似乎可以封装鬼魂的位置,但事实并非如此。因此,如果有人说:

StartPositions p1 = whatever();
... do some stuff
StartPositions p2 = p1;
p2.pacman.X += 3;
p2.ghosts[0].X += 3;

代码会向p2.pacmanp2.ghosts[0]添加三个代码;它不会影响p1.pacman.X,但添加三个p1.ghosts[0]。这种行为可能会引起混淆。

如果您的意图是StartPositions是只读的,它可能永远不会直接暴露ghosts数组;相反,ghosts应该是IList<Vector2>类型的属性,并且您的构造函数应该将其设置为类似于使用传入位置的副本初始化的新ReadOnlyList<Vector2>。如果它这样做,那么ghosts可以只是一个返回这些位置的只读属性。