开发者

Compiler gives error when struct is not initialized and if we try to access the property but not with variable [duplicate]

This question already has answers here: C# Structs: Unassigned local variable? (2 answers) Closed 5 years ago.

I have one observation about struct. When I declare a property in Struct and if I don't initialize the Struct then it gives me the below error - "Use of unassigned local variable empStruct"

PSeduo Code-

struct EmpStruct
{
    private int firstNumber;
    public int FirstNumber
    {
        get { return firstNumber; }
        set { firstNumber = value; }
    }

    public int SecondNumber; 

}

Program.cs-

EmpStruct empStruct;
empStruct.FirstNumber = 5;

But when I declare public variable then the above code works.

EmpStruct empStruct;
empStruct.SecondNu开发者_运维问答mber;

So my question is why compiler not gives error when i try to access variable.(In case of Class it will give the error).


There's a tremendous amount of confusion in this thread.

The principle is this: until all of the fields of an instance of a struct are definitely assigned, you can not invoke any properties or methods on the instance.

This is why your first block of code will not compile. You are accessing a property without definitely assigning all of the fields.

The second block of code compiles because it's okay to access a field without all of the fields being definitely assigned.

One way to definitely assign a struct is to say

EmpStruct empStruct = new EmpStruct();

This invokes the default parameterless constructor for EmpStruct which will definitely assign all of the fields.

The relevant section of the specification is §5.3 on Definite Assignment. And from the example in §11.3.8

No instance member function (including the set accessors for the properties X and Y) can be called until all fields of the struct being constructed have been definitely assigned.

It would be more helpful (ahem, Eric Lippert!) if the compiler error message were along the lines of

Use of not definitely assigned local variable empStruct.

Then it becomes clear what to search for the in the specification or on Google.

Now, note that you've defined a mutable struct. This is dangerous, and evil. You shouldn't do it. Instead, add a public constructor that lets you definitely assign firstNumber and secondNumber, and remove the public setter from EmpStruct.FirstNumber.


Regarding fields C# language Specification says:

10.5.4 Field initialization

The initial value of a field, whether it be a static field or an instance field, is the default value (§5.2) of the field’s type. It is not possible to observe the value of a field before this default initialization has occurred, and a field is thus never “uninitialized

11.3.4 Default values

However, since structs are value types that cannot be null, the default value of a struct is the value produced by setting all value type fields to their default value and all reference type fields to null. The default value of a struct corresponds to the value returned by the default constructor of the struct (§4.1.2).

PS: in case of class it gives error because reference type value by default is null


In your first example, the code doesn't work because local variables have to be initialized before you can use them. There is no "default" value; they must be initialized first. You always have to initialize every local variable before you can use it. For example:

EmpStruct empStruct = new EmpStruct();
empStruct.FirstNumber = 5;

Fields in a class don't have this same restriction. If you don't explicitly initialize them, they will be automatically initialized with default values. In effect, the runtime is automatically calling "new EmpStruct()" on the field in your class. That's why your second example works.


A few code samples might help clarify this better:

// This works because you assign both fields before accessing anything
EmpStruct empStruct;
empStruct.SecondNumber = 2;
empStruct.firstNumber = 1; // I made this public
empStruct.FirstNumber = 3;
Console.WriteLine(empStruct.FirstNumber);
Console.WriteLine(empStruct.SecondNumber);

// This fails because you can't use properties before assigning all the variables
EmpStruct empStruct;
empStruct.SecondNumber = 2;
empStruct.FirstNumber = 3;

// This works because you are only accessing a field that the compiler knows you've assigned
EmpStruct empStruct;
empStruct.SecondNumber = 2;
Console.WriteLine(empStruct.SecondNumber);

// This fails because you haven't assigned the field before it gets accessed.
EmpStruct empStruct;
Console.WriteLine(empStruct.SecondNumber);

The point is, the compiler knows exactly what will happen when you assign a field. But when you assign a property, that might access any number of other fields on the struct. The compiler doesn't know for sure. So it requires you to have all the fields assigned before you can access a property.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜