编译此代码时出错:
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成为一个引用类型(没有事件成员,它正常行事)。发生了什么事?
答案 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
事件处理程序,或者通过新操作初始化整个对象。但是,在任何情况下结构都不会变成参考类型。