How to tell whether a variable has been initialized in C#?
Asked Answered
Z

7

26

I know this is a dumb question and I guess it must have been asked before. However I am unable to find an answer to my question.

Here is some sample code (which of course does not compile) to outline my problem:

class test
{
     int[] val1;
     string val2;

     static bool somefunction(test x, test y)
     {
         dosomestuff()

         test result;

         while(result is nothing)
         {
              if(somecondition){result=new test(something);}
         }
     }
}

The problem which I have is in the following line:

while(result is nothing)

This is the syntax from VB, which of course is not what the C# compiler accepts. Could somebody tell me how to resolve the problem?

Zoroaster answered 28/7, 2009 at 17:41 Comment(1)
Not a dumb question at all. I ran into a lot of this when I went from VB.NET to C#.Devorahdevore
G
25

The syntax you are looking for is:

while (result == null)

You also have to set result = null; to start with also

Gavrilla answered 28/7, 2009 at 17:45 Comment(4)
This will not work with value types. See my answer below for the fixes.Damsel
Yes, but that wasn't the question. The question was asking specifically about a class called test which is not a value type.Gavrilla
(Agreed, your answer is correct and complete with respect to the asker's example. I considered it useful though to point out that it's not complete with respect to the question's more general title; which to me seems far from obvious, but relevant to other people coming across this question.)Damsel
I declare a class but don't initialize it. then if try to check if( myClass == null ) visual sutdio wont let me run this program at all. Error is "use of unsigned local variable"Krein
D
39
  • TL;DR:

    if (Object.Equals(myVariable, default(MyVariableType)))

    • Replace myVariable and MyVariableType.

    There are other solutions.

if (myVariable == null) will not work[1] with value types.
(See further below for short intros to  reference types vs. value types   and structs.)

The value types mainly are structs (e.g. DateTime), including[2] the simple types like int, and enumerations. Value types don't support a null value (intrinsically).

The exception and the fix to this are nullable types: Essentially these add null to the possible values of a struct type. They are structurally the same as the Maybe<T> you might know from other languages[3]. You create them with ValueType? (e.g. int?) which is syntactic sugar for Nullable<ValueType>.


Alternatively, instead of using a nullable type, you could compare your variable to its type's default value:
if (Object.Equals(myVariable, default(MyVariableType)))

(This will work both for reference types (objects) and value types.)
Note that you have to replace MyVariableType manually – unfortunately you can not do

if (Object.Equals(myVariable, default(myVariable.GetType())))

because default() only accepts a type name directly. (I suppose it evaluates at compile-time.)


structs in a nutshell

Put simply, structs are cut-down classes. Imagine classes that don’t support inheritance or finalizers, and you have the cut-down version: the struct. Structs are defined in the same way as classes (except with the struct keyword), and apart from the limitations just described, structs can have the same rich members, including fields, methods, properties and operators.
[Cited from: http://www.albahari.com/valuevsreftypes.aspx ]

Classes are reference types: A class variable (or more specifically, its memory area) only contains a pointer to an other memory area, where the actual object instance data is stored.

Value type variables directly contain the data. This may yield a speed benefit due to cache locality and saving the lookup. But it may also be detrimental to performance in the case of more complex structs.



Footnotes:

[1] It does not even throw an error. myVariable == null will always just yield false, because your myVariable will be initialized with the non-null default value (zero (equivalent) or a struct of zeros and nulls). This default value is available with default(Type).

[2] Technically the simple types (all built-in types except string and object) are structs. Side note: The built-in types are aliases for types from the System namespace.

[3] E.g. in Haskell. In C# Maybe<T> is not built-in, but can be implemented. It provides Nothing as a more explicit/self-documenting version of null both for classes and structs.

[4] There is no [4]. No really, you can go and check.

Damsel answered 15/3, 2012 at 18:47 Comment(1)
Great hint with the ? ValueType.Strew
G
25

The syntax you are looking for is:

while (result == null)

You also have to set result = null; to start with also

Gavrilla answered 28/7, 2009 at 17:45 Comment(4)
This will not work with value types. See my answer below for the fixes.Damsel
Yes, but that wasn't the question. The question was asking specifically about a class called test which is not a value type.Gavrilla
(Agreed, your answer is correct and complete with respect to the asker's example. I considered it useful though to point out that it's not complete with respect to the question's more general title; which to me seems far from obvious, but relevant to other people coming across this question.)Damsel
I declare a class but don't initialize it. then if try to check if( myClass == null ) visual sutdio wont let me run this program at all. Error is "use of unsigned local variable"Krein
V
4
while (result == null)
Vassily answered 28/7, 2009 at 17:44 Comment(3)
The compiler throws the following exception for that: "Use of the unassigned local variable 'test'"Zoroaster
No, since I did not as Colin Mackay suggested set test=null in the first place.Zoroaster
OK. Glad you were able to figure it out.Vassily
B
3
while (result ==null )

if that's what you mean

Berty answered 28/7, 2009 at 17:44 Comment(0)
E
2

Although you have an answer you're happy with, there's something behind this you may find interesting or helpful.

There is a difference between C# and VB.NET. In VB.NET you can write:

Dim b as Boolean

And in C# you can write:

bool b;

They are subtly different. In VB.NET, b has been given the value false (in other words, it has already been initialized). In C#, b has no value (it is uninitialized). C# goes to a lot of effort to make sure you cannot examine the value of a variable that has never been initialized.

So you are not testing whether the variable is initialized. In VB.NET there is no such thing as an uninitialized variable. In C# it is impossible to get the value of an uninitialized variable in order to compare it with anything.

You're testing whether the variable has been initialized to null or Nothing.

Emendate answered 28/7, 2009 at 18:39 Comment(0)
N
1
while(result == null)

The equivalent of nothing in C# is null.

Norseman answered 28/7, 2009 at 17:45 Comment(0)
W
0
while (result == null)
Waves answered 28/7, 2009 at 17:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.