views:

158

answers:

5

I have some code to initialize a struct in C#:

namespace Practice
{
    public struct Point
    {
        public int _x;
        public int _y;

        public int X
        {
            get { return _x; }
            set { _x = value; }
        }

        public int Y
        {
            get { return _y; }
            set { _y = value; }
        }

        public Point(int x, int y)
        {
            _x = x;
            _y = y;
        }    
    }    

    class Practice
    {
        public static void Main()
        {
            Point p1;
            p1.X = 1;
            p1.Y = 2;
        }
    }
}

The above code gives a compiler error:

error CS0165: Use of unassigned local variable 'p1'

Why is this error being thrown?

+3  A: 

You need to create a Point first and assign it to p1:

public static void Main()
{
  Point p1 = new Point();
  p1.X = 1;
  p1.Y = 2;
}

By the way, you can have a constructor on your struct - could make things easier:

//in Point.cs
public point (int x, int y)
{
   _x = x;
   _y = y;
}

//in program.cs
public static void Main()
{
  Point p1 = new Point(1, 2);
}

This also allows you to avoid having setters on a struct (keeping it immutable).

Oded
+14  A: 

You can't use a property in a struct until it knows all the fields have been filled in.

For example, in your case this should compile:

Point p1;
p1._x = 1;
p1._y = 2;
int x = p1.X; // This is okay, now the fields have been assigned

Note how you don't have to explicitly call a constructor here... although in well-encapsulated structs you almost always would have to. The only reason you can get away with this is because your fields are public. Ick.

However, I would strongly advise you not to use a mutable struct anyway. If you really want a struct, make it immutable and pass the values into the constructor:

public struct Point
{
    private readonly int x;
    public int X { get { return x; } }

    private readonly int y;
    public int Y { get { return y; } }

    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

...

Point p1 = new Point(1, 2);
Jon Skeet
I think you mean make it immutable.
Dismissile
@Dismissile: Oops, yes. Fixed.
Jon Skeet
+1  A: 

You have to initialize it with Point p1 = new Point();

Øyvind Bråthen
No you don't. See my answer for an example which will compile and run without any use of `new`.
Jon Skeet
You are absolutely correct. For a mutable struct, you actually don't need to use new, but mutable structs are evil anyway :)
Øyvind Bråthen
A: 

Use Point p1 = new Point();

nin
A: 

The statment: "Point p1;" requires a default constructor. The default constructor will not be automatically prodived because of the public Point(int x, int y) . You need to provide a default constructor: public Point() { ... }

Dinhduy