开发者

Why C# local variables must be initialized?

I am reading MCTS Self Paced Training Kit (70-536) Edition 2 and in the 1st chapter we have the following.

How to Declare a Value Type Variable To use a type, you must first declare a symbol as an instance of that type. Value types have an implicit constructor, so declaring them instantiates the type automatically; you don’t have to include the New keyword as you do with classes. The constructor assigns a default value (usually null or 0) to the new instance, but you should always explicitly initialize the variable within the declaration, as shown in the following code block:

'VB

Dim b As Boolean = False    

// C#  
bool b = false;

However,开发者_运维知识库 when I compile the following Console Application,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ch1_70_536
{
    class Program
    {
        static void Main(string[] args)
        {
            bool b;
            Console.WriteLine("The value of b is " + b);
            Console.ReadKey();
        }
    }
}

I get the Compile Time Error

"Use of Unassigned Local Variable b"

It is not even mentioned in the Errata. Am I doing something wrong or is the book completely wrong?


Local variables have to be assigned before they can be used. Class fields however get their default value.

An example:

public bool MyMethod()
{
    bool a;

    Console.Write(a); // This is NOT OK.

    bool b = false;

    Console.Write(b); // This is OK.
}

class MyClass
{
    private bool _a;

    public void MyMethod()
    {
        Console.Write(_a); // This is OK.
    }
}


The book is mostly correct when it comes to VB, but it fails to mention the difference between VB and C# in this case.

In VB all local variables are automatically initialised:

Sub Test()
  Dim x As Integer
  MessageBox.Show(x.ToString()) 'shows "0"
End Sub

While in C# local variables are not initialised, and the compiler won't let you use them until they are:

void Test() {
  int x;
  MessageBox.Show(x.ToString()); // gives a compiler error
}

Also, it's not clear whether the quote from the book is actually talking about local variables or class member variables. Class member variables are always initialised when the class instance is created, both in VB and C#.

The book is wrong when it says that "Value types have an implicit constructor". That is simply not true. A value type is initialised to its default value (if it's initialised), and there is no call to a constructor when that happens.


You need to assign something to b first otherwise it doesn't get initialized.

try:

bool b = false; 
Console.WriteLine("The value of b is " + b); 

b is now false.


You need to assign a value to b

bool b = false;

Until you assign it a value it is "unassigned"


A variable in a method (method scope) needs to be initialized explicitly. A variable (or 'field') at class level is initialized automatically with the default value.

class Test
{
   bool b; // =false
   int i; // =0
}


Do make it Role of THUMB in C# and VB.net that before calling any variable, do initilize it first. like

int myInt; // Simple Declaration and have no value in it 
myInt= 32; // Now you can use it as there is some value in it..


This statement really should be elaborated to indicate that, although a local variable can be declared without assigning it a value, it cannot be used until it has been assigned an initial value:

The constructor assigns a default value (usually null or 0) to the new instance, but you should always explicitly initialize the variable within the declaration...


In C# local variables are stored in the stack and the compiler does not initialize them to have code optimization.

So the reference, that is in fact a pointer even for value types, points to a undefinded memory space.

Thus if we use a local variable without setting it to someting before, the compiler know that we will get random data.

Here a sample IL code:

static void Test()
{
  int a;
  int b = 2;
}

.method private hidebysig static 
  void Test () cil managed 
{
  // Method begins at RVA 0x3044
  // Code size 4 (0x4)
  .maxstack 1
  .locals init (
    [0] int32 a,
    [1] int32 b
  )

  // (no C# code)
  IL_0000: nop
  // int num = 2;
  IL_0001: ldc.i4.2
  IL_0002: stloc.1
  // }
  IL_0003: ret
} // end of method Program::Test

Int32 is defined in the stack at position 0 for a but it is not assigned to a default value.

So its value is undetermined and can have any value from the memory cells.

For b at position 1, it is assigned later and all is fine.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜