Module 1 · Protect state and design clear object contracts · Lesson 1 of 20
Bridge from Beginner: Diagnose a Study Planner State Bug
You add fifteen minutes to a preview. Why does the saved plan change too?
Use the reference-copying model from Beginner: predict the two printed numbers before running this complete Program.cs in a .NET 10 console project. This diagnostic asks you to turn that model into a method guarantee.
using System;
StudyPlan saved = new StudyPlan("C#", 30);
StudyPlan preview = saved;
preview.Minutes += 15;
Console.WriteLine($"Saved: {saved.Minutes}");
Console.WriteLine($"Preview: {preview.Minutes}");
class StudyPlan
{
public string Topic;
public int Minutes;
public StudyPlan(string topic, int minutes)
{
Topic = topic;
Minutes = minutes;
}
}Count the objects
The output is Saved: 45, then Preview: 45: two variables reach one object, and += changes its Minutes field.
Topic and Minutes are public fields, stored data callers can assign directly. Beginner used properties; the next lesson restricts these mutation routes.
The new requirement is that creating a preview leaves the saved plan unchanged. That invariant is a condition the operation must preserve; the compiler cannot infer it.
What does the first program print?
Show answer
Correct answer: B
Both variables reference the one object whose Minutes field becomes 45.
Option A: Assignment did not create an independent StudyPlan.
Option C: The += statement changes the shared field.
Option D: Multiple references to an object are legal.
Hint: Count constructor calls.
Which change makes a separate preview for this two-field model?
Show answer
Correct answer: C
A constructor call creates the second StudyPlan required by the preview rule.
Option A: Variable names do not control reference semantics.
Option B: That method would still receive a reference to the saved object.
Option D: A third reference still reaches the same object.
Hint: Look for the operation that creates an object.
A future plan adds a List<string> field. What must the copy design consider?
Show answer
Correct answer: A
A separate outer object does not by itself duplicate a referenced list.
Option B: Class assignment copies a reference, including references stored in fields.
Option C: Nested references need their own copying decision.
Option D: Minutes and list contents can still change.
Hint: Draw a second arrow for the list.
Your attempt: an independent preview
Write CreatePreview for a C# plan holding thirty minutes. It receives a ten-minute bonus and returns a separate plan with forty minutes. It must never assign to a source field. A negative bonus must throw ArgumentOutOfRangeException before producing a result; zero is allowed and must still return a separate object.
Before looking below, check both totals and use ReferenceEquals to check that the objects differ.
Hint: a second variable is insufficient. Decide where a second object must be created.
Compare after trying
Copying this string and int into a new object is sufficient for this model.
using System;
StudyPlan saved = new StudyPlan("C#", 30);
StudyPlan preview = CreatePreview(saved, 10);
Console.WriteLine($"Saved: {saved.Topic}, {saved.Minutes}");
Console.WriteLine($"Preview: {preview.Topic}, {preview.Minutes}");
static StudyPlan CreatePreview(StudyPlan source, int bonus)
{
if (bonus < 0)
{
throw new ArgumentOutOfRangeException("bonus");
}
return new StudyPlan(source.Topic, source.Minutes + bonus);
}
class StudyPlan
{
public string Topic;
public int Minutes;
public StudyPlan(string topic, int minutes)
{
Topic = topic;
Minutes = minutes;
}
}Assignment copies the reference. In the first run, both variables reach the same plan, so preview.Minutes += 15 changes what both read to 45. In the separate worked program, CreatePreview(saved, 10) constructs another plan, leaving saved at 30 and producing preview at 40.
If StudyPlan gains a mutable List, decide which nested data the preview must own independently before extending the copy.
Reference: Microsoft: classes, objects, and encapsulation.
Quick reference
- Class assignment copies a reference.
- Count objects separately from variable names.
- Write the expected state before running.
- A new outer object can still share nested mutable objects.
- Refactor around a clear behavior rule.
TechInterviewNotes Editorial Team · Updated 27 Oct 2026 ·