views:

189

answers:

9

What is the proper way to initialize a null variable in .NET? I've been told by one of my colleagues that hard defining of a variable to null is a slowdown.

int var1;          // good practice
string s1;         // good practice

int var2 = 0;      // bad practice
string s2 = null;  // bad practice

Is that correct?

+2  A: 

For an int in .net, it's actually not possible to assign null to it as it's a value type, rather than a reference type, unless you create it as an int? (Nullable<int>), which whilst it is a value type, has special semantics and can thus have null assigned to it.

In your example, there's no point assigning 0 to var2 as the default value for an int is zero. That said, I'd be quite surprised if the c# compiler (although it may be the case tha tthe compiler produces different MSIL for the two) / CLR interpreter treats both as being exactly the same.

private void MyFunction()
{
    int i;
    string s;

    if (s == "3")
    {
        if (i == 1)
        {
        }
    }
}

Bear in mind that in this, ultimately pointless, function, you'd get a compilation error for both the attempt to compare s and i as both are "unassigned locals". This is different from member variables of a class, like:

public class MyClass
{
    int i;

    public void MyFunction()
    {
        if (i == 1)
        {
        }
    }
}
Rob
Got the point .
kofucii
@0xA3, that'll teach me to try using my brain after a glass and a half of wine! =)
Rob
Hehe, but your still quick in updating ;)
0xA3
@0xA3, I have my moments =)
Rob
+1  A: 

I wouldn't say the latter is a bad practice. It's more explicit and a well-known idiom amongst programmers of C-style languages.

Tamás Szelei
+1, but I wouldn't really associate C with C# (a silly thing to do, honestly). That said, I guess the culture might carry over a bit, but since the languages are so different (For example, in C, there are no default values)...
mathepic
That's why I said "C-style".
Tamás Szelei
+5  A: 

Assuming you actually mean the default value instead of a null value, it could slow things down very, very slightly if you actually assign the value in the constructor instead of in the variable declaration. If it's part of the variable declaration I would probably expect the JIT compiler to remove the unnecessary assignment, as the object's memory is wiped on first initialization.

However, the chances of this being significant are absolutely tiny in either case.

Which do you find the more readable form? That's much more important in the vast majority of cases.

EDIT: Note that for static fields at least, there are subtle cases where the two don't behave the same way. Here's an example - the Test1 and Test2 classes differ only in terms of whether the y declaration has an assignment:

using System;

class Test1
{
    static int x = GetX();
    static int y = 0;

    public static void Hello()
    {
        Console.WriteLine("{0} {1}", x, y);
    }

    static int GetX()
    {
        y = 2;
        return 5;
    }
}

class Test2
{
    static int x = GetX();
    static int y;

    public static void Hello()
    {
        Console.WriteLine("{0} {1}", x, y);
    }

    static int GetX()
    {
        y = 2;
        return 5;
    }
}

class Test
{
    static void Main()
    {
        Test1.Hello();
        Test2.Hello(); 
    }
}
Jon Skeet
Isn't the compiler smart enough to generate the same IL for both declarations?
Tamás Szelei
@sztomi: The C# compiler doesn't. Whether the JIT compiler does is a different matter.
Jon Skeet
bcoz, `The default value of an integral type is equivalent to the literal 0`. (via MSDN)
Ankit Jain
@Ankit: Yes, I know it's the default value. But there are subtle cases where it may actually make a difference, at least for static fields.
Jon Skeet
+1  A: 

An integer is a value type, so it can't be initialized to null.

The performance loss for pre-initialization is arguably negligible, but if it isn't necessary, it should be avoided. For details, check out how to gain performance by not initializing variables. Also, check out Jeff Atwood's blog post: For Best Results, Don't Initialize Variables.

senfo
+1  A: 

Any uninitialized use of a variable in C# will generate a compiler warning (if there is at least one code path the do not initializes). And there should not be any warnings in your final code!

In the second statement you are specifying a default value. In the first statement you have assumed that all code-paths will assign some value to it.

Ankit Jain
+1  A: 

You'll want to initialize local variables of reference type to null if there is no other explicit value assigned, or you will run into "uninitialized local variable" compile errors. Example:

Err

// Inside a method, property or indexer.
Random r; // compile error - Uninitialized local var

The same goes for other kinds of local variables, both reference and value type. In your example it uses a value type and the local variable should be declared:

int var1 = 0;

The same good form for reference types is:

// Inside a method, property or indexer.
Random r = null;

On the other hand Fields e.g. "member variables" are at the class level you don't need to assign an explicit value to these.

See also:

John K
A: 

You cannot assign null to a value type such as int. However, in later versions of .NET, you can use nullable value types:

int? var1 = null;

It is not a bad practice to initialize variables in their declarations. In fact, it's quite the opposite. By doing so, there's no question in anyone's mind about the value of the variable after it's declared.

Also, there's such a minimal performance penalty for assigning null to a variable that you needn't worry about it. Focus on programming for accurate functionality before anything else; once you have that, then adjust for any glaring performance issues that may arise.

+1  A: 

If you are talking about member variables, there is maybe another reason to not initialize them with their default values: the FxCop compliance to the rule CA1805: DoNotInitializeUnnecessarily.

If one of the requirements is to write FxCop compliant code, you cannot initialize variables with default values.

MainMa
Maybe you wanted to differentiate between local variables and member variables (fields)?
Ben Voigt
@Ben Voigt: answer modified. Thanks to note the difference.
MainMa
+1  A: 

The CLR makes a hard promise that all local variables will be initialized to their default value upon entry into the method before the first statement is executed. This promise is implemented by the JIT compiler. Seeing this is a bit difficult since the C# requires variables to be initialized explicitly before they are used. But here's an example:

    static void Main(string[] args) {
        int ix;
        int.TryParse("42", out ix);
        Console.WriteLine("", ix);
    }

Use Debug + Windows + Disassembly to see the generated code:

// Stack frame setup elided...
00000006  xor         eax,eax                        ; eax = 0
00000008  mov         dword ptr [ebp-0Ch],eax        ; ix = 0
// etc..

Rewriting this to initialize ix to zero produces this code:

00000006  xor         eax,eax                        ; eax = 0
00000008  mov         dword ptr [ebp-0Ch],eax        ; ix = 0
0000000b  xor         edx,edx                        ; edx = 0
0000000d  mov         dword ptr [ebp-0Ch],edx        ; ix = 0

Well, that's a bit sad. The JIT compiler is usually quite good at optimizing useless code away but fumbles in this particular case.

So, you're friend is right. At least for the x86 JIT compiler, not close to an x64 machine right now. The overhead is probably around half a nanosecond or so. Not something that is easy to measure.

Hans Passant