为什么我会创建此错误&返回一个新结构?

时间:2008-11-18 00:33:21

标签: c# reference events struct compiler-errors

编译此代码时出错:

using System;

public struct Vector2
{
    public event EventHandler trigger;

    public float X;
    public float Y;

    public Vector2 func()
    {
        Vector2 vector;
        vector.X = 1;
        vector.Y = 2;
        return vector;  // error CS0165: Use of unassigned local variable 'vector'
    }
}

喜!

编译器说:“使用未分配的局部变量'vector'”并指向返回值。在我看来,Vector2成为一个引用类型(没有事件成员,它正常行事)。发生了什么事?

3 个答案:

答案 0 :(得分:14)

在C#中,除非要初始化所有字段,否则仍需要“新建”结构来调用构造函数。你没有分配EventHandler成员'trigger'。

尝试分配“触发器”或使用:

Vector2 vector = new Vector2()

新对象在堆上分配 not ,它仍然在函数堆栈上分配。

引用MSDN

  

使用时创建struct对象   新的运算符,它被创建和   调用适当的构造函数。   与类不同,结构可以是   实例化而不使用新的   运营商。 如果您不使用新的,   字段将保持未分配状态,   对象无法使用直到所有   字段已初始化。

答案 1 :(得分:2)

其他人已经解释了解决这个问题的方法,但我认为值得一提的是你的代码存在另一个重大问题:你有一个可变的结构。那些总是一个坏主意。这肯定只是你遇到的许多问题中的第一个问题。

强烈建议你让它变成不可变的或者让它成为一个类。

答案 2 :(得分:1)

Rob Walker有更好的回应,因为他从文档开始然后推理到代码(而我反过来)。

如果您使用已注释掉的触发器字段编译示例代码,然后运行IlAsm以获取生成的MSIL,您将看到本地变量向量没有initobj操作码。

initobj结构只包含值类型时,缺少Vector2就可以了。毕竟他们只是原始记忆。但是,如果Vector2结构也包含引用,则必须对其进行初始化,以防止出现未初始化的对象引用。

为了避免返回部分单元化对象,您需要显式写入trigger事件处理程序,或者通过新操作初始化整个对象。但是,在任何情况下结构都不会变成参考类型。