3

编译此代码时出现错误:

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 变成了一个引用类型(没有它正常运行的事件成员)。怎么了?

4

3 回答 3

14

在 C# 中,除非您正在初始化所有字段,否则您仍然需要“新建”一个结构来调用构造函数。您未分配 EventHandler 成员“触发器”。

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

Vector2 vector = new Vector2()

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

引用MSDN

当您使用 new 运算符创建结构对象时,它会被创建并调用相应的构造函数。与类不同,结构可以在不使用 new 运算符的情况下进行实例化。如果不使用 new,则这些字段将保持未分配状态,并且在所有字段都初始化之前无法使用该对象。

于 2008-11-18T00:38:59.930 回答
2

其他人已经解释了解决这个问题的方法,但我认为值得一提的是你的代码的另一个大问题:你有一个可变结构。这些几乎总是一个坏主意。如果你保持这种状态,这肯定只是你会遇到的许多问题中的第一个。

强烈建议你要么让它不可变,要么让它成为一个类。

于 2008-11-18T06:32:10.827 回答
1

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

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

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

为了避免返回部分未初始化的对象,您需要trigger显式地写入事件处理程序,或者通过新操作初始化整个对象。但是,在任何情况下都不会将结构转换为引用类型。

于 2008-11-18T00:53:13.817 回答