Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initially assigned variables

The following two categories of variables are initially assigned:

  • Instance variables of class instances.

  • Instance variables of initially assigned struct variables.

Now what does initially assigned struct variables mean?

We're not talking about local variable, right? So we're talking about field variables (in both of these categories) that are used in function member definitions?

Clarifying this would be really appreciated. And thanks in advance!

like image 630
Garrett Biermann Avatar asked Apr 12 '26 00:04

Garrett Biermann


2 Answers

The following two categories of variables are initially assigned: (1) Instance variables of class instances and (2) Instance variables of initially assigned struct variables. What does "initially assigned struct variables" mean?

It means an initially assigned variable of struct type.

Follow along.

class C 
{
    public int i;
}
...
C c = new C();
Console.WriteLine(c.i);

c.i is an instance variable of a class, so it is initially assigned.

struct S 
{
    public int j;
}
class D 
{
    public S t;
}
...
D d = new D();
Console.WriteLine(d.t.j);

d.t is an instance variable of a class, so it is initially assigned. d.t.j is an instance variable of a struct S, and the variable d.t of type S is initially assigned, therefore d.t.j is also initially assigned.

That is, a field of a struct is initially assigned if the variable that holds the value of the struct is itself initially assigned.

By contrast:

void M()
{
    int q;
    Console.WriteLine(q); // Error
    S u;
    Console.WriteLine(u.j); // Error

Neither q nor u are initially assigned; they are not fields of any class. Since u is not initially assigned, u.j is not either.

Make sense now?

like image 167
Eric Lippert Avatar answered Apr 14 '26 14:04

Eric Lippert


Your question is not very clear. But it is correct that a field (instance or static) of a class or struct is always considered assigned. It will have the default value of the type, which is null for reference types and nullable types, and "zero" or something similar to zero for other value types.

In contrast a local variable, that is a variable declared inside a method (or constructor, or accessor, etc.) must be explicitly assigned to before it is used.

In the example:

class Example
{
    int field;

    void Method()
    {
        int local;
        ...
        ...
    }
}

the field is considered assigned automatically and will have the initial value 0, whereas the variable local is unassigned and must be assigned to (later in the same method) before it can be used (even later in the same method).

An unassigned local variable may be passed as an out parameter of a method, though.

EDIT: (after helpful comments)

My answer above gives a pretty precise description for (static and non-static) fields of classes and for static fields of structs. But there was missing something, as the comments pointed out, in case of instance fields of structs.

A struct instance is fully assigned when all its instance fields are fully assigned. Given the following (mutable!!) struct:

struct SomeStruct
{
    public int AlphaField;
    public int BetaField;
}

then the following is legal:

void M()
{
    SomeStruct localSS;
    // localSS and its fields are not assigned, and can't be read yet

    localSS.AlphaField = 7;           // legal
    int useA = localSS.AlphaField;    // legal, AlphaField is assigned
    // localSS and its remaining field BetaField are not assigned

    localSS.BetaField = 13;
    string useB = localSS.ToString(); // legal, localSS variable is now fully assigned
}

Even if the above example seems crazy (because mutable structs are discouraged by most people), it is still entirely equivalent to what happens inside a user-defined instance constructor of a struct. The C# Specification uses this sentence: The this variable of an instance constructor of a struct behaves exactly the same as an out parameter of the struct type—in particular, this means that the variable must be definitely assigned in every execution path of the instance constructor.

Note that one way for an instance constructor of a struct to assign all fields, is to chain another instance constructor with the : this(...) constructor chaining syntax.

Also note that instance constructors of structs must take parameters. The expression new SomeStruct() (with empty parameter list) is equivalent to default(SomeStruct) and evaluates to the definitely assigned instance of SomeStruct where all fields have their default values.

like image 21
Jeppe Stig Nielsen Avatar answered Apr 14 '26 12:04

Jeppe Stig Nielsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!