27

From the documentation:

Unlike classes, structs can be instantiated without using a new operator.

So why am I getting this error:

Use of unassigned local variable 'x'

When I try to do this?

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

Where Vec2 x is a struct?

0

2 Answers 2

27

Well, are X and Y properties (rather than fields)? If so, that's the problem. Until all the fields within x are definitely assigned, you can't call any methods or properties.

For instance:

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
    }
}

Is Vec2 your own type? Do you have access to the fields involved, or only the properties?

If it's your own type, I would strongly urge you to try to stick to immutable structs. I know managed DirectX has some mutable structs for getting as close to optimal performance as possible, but that's at the cost of strange situations like this - and much worse, to be honest.

I would personally give the struct a constructor taking X and Y:

 Vec2 x = new Vec2(det * (a22 * b.X - a12 * b.Y),
                   det * (a11 * b.Y - a21 * b.X));
Sign up to request clarification or add additional context in comments.

7 Comments

Ah, they were properties. Good catch! I'll consider making X and Y private if I can get away with it.
I am very new to this and would definitely appreciate an answer to this doubt: If I can set x directly as shown, what is the use of having a setter method? I have the same problem, however, the struct I have has x set as private public getter and setter methods to manipulate it. How should I work with that?
@darnir: The use is that you normally wouldn't make the field publicly available. Your situation isn't really clear, and is probably worth a separate question - I'd expect there to be a constructor taking all the relevant fields.
@JonSkeet: Thanks for your reply. There was no constructor to the struct I was using. I made all the fields private and created a constructor for the struct. It now works fine.
It seems the compiler is also not happy if you set any of the fields in an if/else, even though it is definitely set as a result.
|
9

It is still uninitialized. You need to initialize it before using it. You can use default operator for that if you don't want to create a static Vec.Empty value and happy with the defaults for the structs members:

Vec2 x = default(Vec2);

Mitch Wheat:

This, however doesn't:

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; 
}

The compiler prevents you from calling propertis on types before all of it's members have been initialized, even though a property might just set one of the values. The solution, as Jon Skeet proposed, is to have an initializing constructor and preferably no setters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.