Superbest
Superbest

Reputation: 26632

C# - checking if a variable is initialized

I want to check if a variable is initialized at run time, programmatically. To make the reasons for this less mysterious, please see the following incomplete code:

string s;

if (someCondition) s = someValue;
if (someOtherCondition) s = someOtherValue;

bool sIsUninitialized = /* assign value correctly */;

if (!sIsUninitialized) Console.WriteLine(s) else throw new Exception("Please initialize s.");

And complete the relevant bit.

One hacky solution is to initialize s with a default value:

string s = "zanzibar";

And then check if it changed:

bool sIsUninitialized = s == "zanzibar";

However, what if someValue or someOtherValue happen to be "zanzibar" as well? Then I have a bug. Any better way?

Upvotes: 40

Views: 113098

Answers (9)

GlabbichRulz
GlabbichRulz

Reputation: 1014

I would suggest initializing the variable with null:

MyType? myVar = null;

You can then check whether it has been set to an non-null value using:

var isSet = myVar != null;

Upvotes: 0

I would agree with Vytalyi that a default value of null should be used when possible, however, not all types (like int) are nullable. You could allocate the variable as a nullable type as explained by David W, but this could break a lot of code in a large codebase due to having to refine the nullable type to its primitive type before access.

This generic method extension should help for those who deal with large codebases where major design decisions were already made by a predecessor:

public static bool IsDefault<T>(this T value) 
        => ((object) value == (object) default(T));

If you are staring from scratch, just take advantage of nullable types and initialize it as null; that C# feature was implemented for a reason.

Upvotes: 1

McGarnagle
McGarnagle

Reputation: 102793

Code won't even compile if the compiler knows a variable hasn't been initialized.

string s;
if (condition) s = "test";
// compiler error here: use of unassigned local variable 's'
if (s == null) Console.Writeline("uninitialized");

In other cases you could use the default keyword if a variable may not have been initialized. For example, in the following case:

class X
{ 
    private string s;
    public void Y()
    {
        Console.WriteLine(s == default(string));  // this evaluates to true
    }
}

The documentation states that default(T) will give null for reference types, and 0 for value types. So as pointed out in the comments, this is really just the same as checking for null.


This all obscures the fact that you should really initialize variables, to null or whatever, when they are first declared.

Upvotes: 28

Peter Gluck
Peter Gluck

Reputation: 8236

In general, assign the default to be null or String.Empty. For situations where you cannot use those "empty" values, define a constant to represent your application-specific uninitialized value:

const string UninitializedString = "zanzibar";

Then reference that value whenever you want to initialize or test for initialization:

string foo = UnininitializedString;
if (foo == UninitiaizedString) {
  // Do something
}

Remember that strings are immutable constants in C# so there is really only one instance of UninitializedString (which is why the comparison works).

Upvotes: -4

David W
David W

Reputation: 10184

With C# 2.0, you have the Nullable operator that allows you to set an initial value of null for heretofore value types, allowing for such things as:

int? x = null;

if (x.HasValue)
{
    Console.WriteLine("Value for x: " + num.Value); 
}

Which yields: "Value for x: Null".

Upvotes: 13

Tim Goodman
Tim Goodman

Reputation: 23986

Here's one way:

string s;
if (someCondition) { s = someValue; }
else if (someOtherCondition) { s = someOtherValue; }
else { throw new Exception("Please initialize s."); }

Console.WriteLine(s)

This might be preferable for checking if the string is null, because maybe someValue is a method that can sometimes return null. In other words, maybe null is a legitimate value to initialize the string to.

Personally I like this better than an isInitialized flag. Why introduce an extra flag variable unless you have to? I don't think it is more readable.

Upvotes: 3

Vytalyi
Vytalyi

Reputation: 1695

Just assign it null by default, not a string value

Upvotes: 11

Sam Axe
Sam Axe

Reputation: 33738

I pick initialization values that can never be used, typical values include String.Empty, null, -1, and a 256 character random string generator .

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727067

You can keep a separate flag that indicates that the string has been initialized:

string s = null;
bool init = false;
if (conditionOne) {
    s = someValueOne;
    init = true;
}
if (conditionTwo) {
    s = someValueTwo;
    init = true;
}
if (!init) {
    ...
}

This will take care of situations when s is assigned, including the cases when it is assigned null, empty string, or "zanzibar".

Another solution is to make a static string to denote "uninitialized" value, and use Object.ReferenceEquals instead of == to check if it has changed. However, the bool variable approach expresses your intent a lot more explicitly.

Upvotes: 2

Related Questions