Skip to content
Search lessons, topics, tests…
Esc

    ↑ ↓ moveEnter openEsc close
    Lesson2 / 20

    Protect Object State with Constructors and Methods

    A session starts at twenty-five minutes. Adding ten should work; adding negative five should leave the total alone. Where must those rules live if callers cannot be trusted to check them?

    Predict the two Boolean results and the final total, then run this complete program.

    C#
    using System;
    
    StudySession session = new StudySession("  C#  ", 25);
    Console.WriteLine(session.TryAddMinutes(10));
    Console.WriteLine(session.TryAddMinutes(-5));
    Console.WriteLine($"{session.GetTopic()}: {session.GetMinutes()}");
    
    class StudySession
    {
        private string topic;
        private int minutes;
    
        public StudySession(string topic, int minutes)
        {
            if (string.IsNullOrWhiteSpace(topic))
            {
                throw new ArgumentException("Topic is required.", "topic");
            }
            if (minutes < 0)
            {
                throw new ArgumentOutOfRangeException("minutes");
            }
    
            this.topic = topic.Trim();
            this.minutes = minutes;
        }
    
        public string GetTopic()
        {
            return topic;
        }
    
        public int GetMinutes()
        {
            return minutes;
        }
    
        public bool TryAddMinutes(int extra)
        {
            if (extra <= 0 || extra > int.MaxValue - minutes)
            {
                return false;
            }
    
            minutes += extra;
            return true;
        }
    }

    Follow the accepted change

    The output is True, False, then C#: 35. The constructor trims the topic and rejects an invalid starting state. TryAddMinutes rejects a later unsuitable request by returning false, leaving the object usable.

    RequestDecisionTotal afterward
    Construct with 25Nonnegative starting total25
    Add 10Positive and fits int35
    Add -5Reject before assignment35

    The private field can be accessed inside its declaring class. The public methods are the operations available to callers. this.minutes means the current object's field; minutes alone names the constructor parameter there. The Get methods expose values without exposing assignments. The next lesson replaces that reading syntax with properties.

    Private access alone is insufficient: a public method could still write an invalid value. Search for assignments to the field. Initialization and the accepted update are the only routes, and both have checks.

    The capacity check uses int.MaxValue - minutes before adding. Since the existing total is nonnegative, the subtraction is safe. An extra amount larger than that remaining capacity is rejected before it can overflow. Zero is deliberately rejected too: this method accepts positive additions.

    What is the final minute total in the prediction program?

    A 20
    B 25
    C 30
    D 35
    Show answer

    Correct answer: D

    Ten is accepted and negative five is rejected without mutation.

    Option A: The negative request is not subtracted.

    Option B: The first update succeeds.

    Option C: A rejected update does not partially apply.

    Hint: Trace only assignments that are reached.

    Why check extra > int.MaxValue - minutes before adding?

    A It sorts additions
    B It rejects additions that cannot fit in int
    C It converts minutes to a string
    D It allows negative totals
    Show answer

    Correct answer: B

    The remaining capacity can be compared safely before computing the sum.

    Option A: There is no ordering operation.

    Option C: The expression uses integer arithmetic.

    Option D: The constructor and guards preserve a nonnegative total.

    Hint: The field already holds a nonnegative value.

    Which public API best preserves the session rule?

    A A public minutes field and comments asking callers to behave
    B A public method that assigns any integer directly
    C Private state with a method that validates before assignment
    D A getter that resets minutes whenever it is read
    Show answer

    Correct answer: C

    Every supported mutation passes the rule before changing state.

    Option A: Comments cannot prevent direct invalid assignments.

    Option B: Moving an unchecked assignment into a method does not enforce the rule.

    Option D: Reading should not unexpectedly erase accumulated state.

    Hint: Inspect every route that writes the field.

    Build a goal that rejects the whole request

    Create StudyGoal with a positive target and an initially zero completed total. TryComplete accepts only a positive amount that will not exceed the target. A rejected request changes nothing.

    Use a target of sixty and try twenty, fifty, then forty. Write the completed total after each call before implementing the method. Your checks must prove that the rejected fifty does not consume any of the remaining goal.

    Hint: compare the request with the remaining capacity before changing completed.

    Check your solution

    Expect True, False, True, then Completed: 60. The last request reaches the target exactly.

    C#
    using System;
    
    StudyGoal goal = new StudyGoal(60);
    Console.WriteLine(goal.TryComplete(20));
    Console.WriteLine(goal.TryComplete(50));
    Console.WriteLine(goal.TryComplete(40));
    Console.WriteLine($"Completed: {goal.GetCompleted()}");
    
    class StudyGoal
    {
        private int target;
        private int completed;
    
        public StudyGoal(int target)
        {
            if (target <= 0)
            {
                throw new ArgumentOutOfRangeException("target");
            }
    
            this.target = target;
        }
    
        public int GetCompleted()
        {
            return completed;
        }
    
        public bool TryComplete(int amount)
        {
            if (amount <= 0 || amount > target - completed)
            {
                return false;
            }
    
            completed += amount;
            return true;
        }
    }

    Point to the guard that preserves the total after rejection. Throwing during invalid construction and returning false for an ordinary rejected update are choices for this model; they are not rules every API must follow.

    Reference: Microsoft: constructors.

    Quick reference

    • Constructors establish starting rules.
    • Private fields restrict direct writes.
    • Validate every supported mutation before assignment.
    • A Try method can return false without changing state.
    • Check numeric capacity before addition.
    Sign in to mark lessons done and keep your place in the course.Sign in

    TechInterviewNotes Editorial Team · Updated 27 Oct 2026 ·