C# 结构体:未分配的本地变量?

27

根据文档:

与类不同,结构体可以在不使用 new 操作符的情况下进行实例化。

那我为什么会收到这个错误:

使用了未赋值的局部变量“x”

当我尝试做这个时?

        Vec2 x;
        x.X = det * (a22 * b.X - a12 * b.Y);
        x.Y = det * (a11 * b.Y - a21 * b.X);

Vec2 x是一个结构时?

2个回答

27

好的,那么X和Y是属性(而不是字段)吗?如果是这样,那就是问题所在。在确定赋值之前,您不能调用任何方法或属性。

例如:

public struct Foo
{
    public int x;
    public int X { get { return x; } set { x = value; } }
}

class Program
{
    static void Main(string[] args)
    {
        Foo a;
        a.x = 10; // Valid

        Foo b;
        b.X = 10; // Invalid
    }
}

你的Vec2是自己的类型吗?你能够访问所涉及的字段,还是只能访问属性?

如果这是你自己的类型,我强烈建议你尝试使用不可变的结构体。我知道受控的DirectX有一些可变的结构体,以尽可能接近最佳性能为目标,但这是以牺牲诸如此类奇怪情况等更糟糕的后果为代价的。

我个人会给结构体一个带有X和Y的构造函数:

 Vec2 x = new Vec2(det * (a22 * b.X - a12 * b.Y),
                   det * (a11 * b.Y - a21 * b.X));

我对这个非常新,肯定会感激一个关于这个疑问的答案:如果我可以直接设置x,那么有setter方法有什么用呢?我有同样的问题,然而,我有一个将x设置为私有的结构体,以及公共的getter和setter方法来操作它。我应该如何处理这个? - darnir
@darnir:使用场景通常是您不会将字段公开。您的情况并不是很清楚,可能值得提出一个单独的问题 - 我期望有一个构造函数来接收所有相关字段。 - Jon Skeet
似乎编译器也不高兴,即使它明确设置了结果,如果您在if/else中设置任何字段。 - xr280xr
@xr280xr 我认为这应该可以工作 - 你能在gist中重现吗? - Jon Skeet
@JonSkeet - 我无法重现它!也许我之前某个字段打错了,或者VS出了问题。抱歉&谢谢! - xr280xr
显示剩余2条评论

9

它仍未初始化。在使用前你需要对其进行初始化。如果你不想创建一个静态的Vec.Empty值并且满足结构体成员的默认值,可以使用default运算符来完成初始化:

Vec2 x = default(Vec2);

Mitch Wheat:

这个很明显,但是以下的内容可能不是:

public struct Vec2
{
    int x;
    int y;

   public float X { get { return x; } set { x = value; } }
   public float Y { get { return y; } set { y = value; } }

}
static void Main(string[] args)
{
    Vec2 x;

    x.X = 1;
    x.Y = 2; 
}

即使属性只设置一个值,编译器也会防止您在类型的所有成员被初始化之前调用属性。解决方案是像Jon Skeet所建议的那样拥有一个初始化构造函数,最好不要有setter。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接