Oliver
Oliver

Reputation: 11607

Do properties always have a value when unset?

I have a property like this:

public Tuple<String, String>[] Breadcrumbs { get; set; }

and I have a test in one of my methods like this:

if (Breadcrumbs != null && Breadcrumbs.Length > 0) { }

Depending on when this method is called, Breadcrumbs may not have been set. In one test, Breadcrumbs == null evaulates to true.

Will unset properties always have a value? (Will it always be null?)

Upvotes: 9

Views: 4668

Answers (4)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112402

Class member variables (called fields), and thus backing variables of properties, are always initialized to their default value, if they are not initialized explicitly, which is null for reference types. The default value for all types is the value whose binary representation consists of all bits set to 0.

On the other hand, C# requires you to initialize local variables explicitly. These are: variables declared in methods, constructors and property accessors and out method parameters; i.e. they are treated as undefined until you assign them a value.

Upvotes: 2

Jon Hanna
Jon Hanna

Reputation: 113292

It's logically impossible for it not to have a value. It's going to have to return something, some bunch of 1s and 0s that is at least believed to be a reference to a Tuple<String, String>[], so to that extent it has a value.

It's also the case that all fields in classes get set to their default value (default(T) for whatever type T they are, which is null for all reference types). Otherwise it would be possible to have an object that was in a state that not only didn't make any sense in terms of what it does, but which didn't make any sense by the rules of what .NET expects objects to do. This includes the hidden fields behind automatic properties.

Now, in some languages we can do the equivalent of this:

public Tuple<String, String>[] Breadcrumbs
{
  get
  {
    Tuple<String, String>[] whatIWillSend;
    return whatIWillSend;
  }
}

If this were allowed, whatIWillSend would have a value defined not by any concious decision on your part, but by what happened to be in memory at the time. It could be null, it could be a valid Tuple<String, String>[] by sheer coincidence (but not the one you wanted to use!), it could be a Dictionary<int, List<string>> that the runtime is now going to think is actually a Tuple<String, String>[] (there goes the type-safety of the entire system), it could be a quarter of a decimal structure. (In the languages that allow such things, it could also be a well-known value that debuggers for such languages set in these cases precisely so to help find bugs caused by it).

That's the closest thing we can get to a property not having a value. Note though that:

  1. It would still have a value, just not a meaningful value.
  2. We aren't allowed to do this in C# anyway.

Upvotes: 0

Gilad Naaman
Gilad Naaman

Reputation: 6550

Auto-properties use backing fields and are compiled to regular properties.

If the Property-Type is a reference type the value would be null, if not the value would be the default value.

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1500903

An automatically-implemented property which hasn't been explicitly set by any code will always have the default value for the property type - which is null for reference types. (For int it would be 0, for char it would be '\0' etc).

An automatically implemented property like this is just equivalent to:

private PropertyType property;
public PropertyType Property
{
    get { return property; }
    set { property = value; }
}

... except that the backing variable has an unspeakable name (you can't refer to it in code) so it will always start off with the default value for the type.

Upvotes: 19

Related Questions