After you assign an object relationship:
player1.team = team1;
the Player object has a reference to a Team object.
The program can follow that relationship with the dot operator.
For example:
player1.team
means:
the Team object referenced by the
teamfield onplayer1
If the Team has a field named:
name
then:
player1.team.name
follows the relationship one step farther.
Consider:
player1.team.name
Read it in stages.
player1Start with the Player object.
.teamAccess the Player's Team reference.
.nameAccess the name field on that Team object.
Plain language:
Get
player1's Team object, then get that Team object's name.
Suppose UML contains:
player1 : Player -------- team1 : Team
----------------
name = "Wildcats"
After the relationship is assigned in C#:
player1.team = team1;
the expression:
player1.team.name
can reach the Team object's name.
The nested source follows the relationship shown in UML.
For:
player1.team.name
the program needs:
player1 → Player object
and:
player1.team → Team object
If either required reference is null, the member-access chain cannot continue normally.
That is why nested member access frequently appears in NullReferenceException diagnosis.
A long expression can hide which reference failed.
Instead of thinking about:
player1.team.name
as one indivisible expression, think:
Step 1: player1
Step 2: player1.team
Step 3: player1.team.name
Inspect Step 1.
Then Step 2.
Once you find null, you know the later step cannot succeed.
This sequence is unsafe if team is still null:
Player player1 = new Player();
player1.team.name = "Wildcats";
The program tries to reach:
player1.team
before the relationship has been established.
A relationship-aware sequence is:
Player player1 = new Player();
Team team1 = new Team();
player1.team = team1;
team1.name = "Wildcats";
Now the related Team object exists and the Player points to it before nested access depends on that relationship.
Once team1 exists, these expressions can refer to the same Team object's name after the relationship is assigned:
team1.name
and:
player1.team.name
The first starts directly from team1.
The second demonstrates the relationship path through player1.
Choose the expression required by the current task and supplied source.
Do not rewrite code merely to prefer one form.
You may eventually encounter longer chains.
For now, do not rush into complicated object graphs.
Use the same rule repeatedly:
current object/reference
↓ dot
next member/reference
↓ dot
next member
Every intermediate reference must lead to the expected object.
When reading:
player1.team.name
picture:
player1 : Player
|
v
team1 : Team
name = "Wildcats"
That visual model makes the member chain easier to interpret.
The next activity uses the debugger to inspect nested objects directly.