When C# creates an object:
Player player1 = new Player();the object exists immediately after the statement executes.
Its fields already have values.
If the supplied class has not established another initial value, C# fields begin with default values based on their types.
This matters because:
does not mean:
For the basic field types already introduced, useful defaults include:
| Field type | Default field value |
|---|---|
| int | 0 |
| double | 0.0 |
| bool | false |
| reference type such as string or another class | null |
For example, if Player contains:
string name;
int jerseyNumber;
bool isAvailable;then a newly created object may initially have conceptual state like:
name = null
jerseyNumber = 0
isAvailable = falseuntil other code assigns different values.
Suppose the UML requires:
jerseyNumber = 7The new object's default:
jerseyNumber = 0does not satisfy that requirement.
The field must be assigned the required state.
Likewise, if UML requires:
isAvailable = truethe default Boolean value:
falseis not correct for that snapshot.
A default value is simply the value C# provides when no other field initialization has established a different state.
Sometimes the default is appropriate.
Sometimes it is temporary.
Sometimes it reveals that required initialization has not happened yet.
The meaning depends on the program.
Suppose a Player object has a field that can refer to a Team object.
Conceptually:
Team team;Before the program assigns an actual Team object, that reference field can have the default value:
nullnull means the reference does not currently point to an object.
That becomes important when code tries to use the dot operator through the reference.
For a string field:
nulland:
""are different states.
null means the reference does not currently refer to a string object/value instance.
"" is an empty string containing zero characters.
You do not need to perform advanced string handling here.
Simply recognize that they are not interchangeable.
A default numeric value can be confusing because 0 may also be meaningful.
For example:
goals = 0can be a valid soccer state.
The debugger cannot tell you from the value alone whether 0 is:
Use the requirement and execution path as evidence.
A useful runtime moment is directly after:
Player player1 = new Player();Pause execution and inspect player1.
Before later assignments execute, you can see the object's initial field state.
Then step over:
player1.name = "Jordan";
player1.jerseyNumber = 7;
player1.isAvailable = true;and observe the values change.
This shows the difference between:
object creation
and:
scenario-state assignment.
Suppose an object contains a reference field whose current value is:
nullIf code later tries to access a member through that reference, the program can fail at runtime.
That is one common path to a NullReferenceException.
CO-029 focuses directly on diagnosing that situation.
After new:
The debugger helps you observe that state rather than guessing what a new object contains.