Featured resource
2026 Tech Forecast
2026 Tech Forecast

1,500+ tech insiders, business leaders, and Pluralsight Authors share their predictions on what’s shifting fastest and how to stay ahead.

Download the forecast
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Shape Text and Employee Behavior in C#

Contoso Staffing's HR reps type new-hire details directly into a console tool during onboarding: names, department codes, and badge numbers arrive with inconsistent spacing and casing. The toolkit you build cleans that raw text, slices badge codes into their department-prefix and employee-number parts, masks sensitive digits when displaying them, and turns the cleaned data into Employee objects that track hire behavior like check-ins and tenure. By the end, HR reps can type messy input and get back a consistent, safely encapsulated employee directory entry.

Lab platform
Lab Info
Level
Beginner
Last updated
Oct 05, 2026
Duration
45m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use, and consent to receive marketing emails from Pluralsight.
Table of Contents
  1. Challenge

    Step 1: Orientation - Meet the employee onboarding toolkit

    Step 1: Orientation - Meet the employee onboarding toolkit

    Contoso Staffing's HR reps type new-hire details straight into a console tool while they're on the phone with a hiring manager: names arrive as jamie rivera or JAMIE RIVERA, department codes as eng or ENG, and badge numbers as a single unbroken string like ENG4821. None of that text is safe to store or display as-is. Over the next four steps you'll build a small toolkit that cleans it up, slices it apart, and turns it into a properly modeled Employee object. ## Where you'll work

    All of your edits happen under src/:

    • src/InputNormalizer.cs - trims and case-normalizes raw console text, and compares normalized values for equality.
    • src/BadgeProcessor.cs - slices badge codes like ENG4821 into a department prefix and an employee number, and builds a masked version for display.
    • src/Employee.cs - models a hired employee with fields for name, department, badge code, and hire date, plus behavior for tenure and check-ins.
    • src/OnboardingService.cs - wires the normalizer, the badge processor, and the Employee class together into one onboarding flow.

    Each file already compiles; the methods you'll complete are marked with // TODO comments. Run bash runTest.sh Task_2_1, with any task's number, at any point to check that task on its own. ## How the steps build on each other

    • Step 2 puts you in InputNormalizer.cs, working with raw strings straight from the console: declaring and reading them, then trimming and case-normalizing so eng and ENG are recognized as the same value.
    • Step 3 moves to BadgeProcessor.cs, where you'll use zero-based Substring calls to pull a badge code apart and build a masked replacement without ever changing the original string - strings in C# can't be mutated in place.
    • Step 4 introduces Employee.cs: a class with fields that hold an employee's state, and instance methods that compute tenure and record check-ins from that state.
    • Step 5 locks those fields behind private access, adds a validated way to change them, and finally assembles all three files into a working onboarding pipeline in OnboardingService.cs.

    By the end, a single call chain will take messy console text all the way to a safely encapsulated Employee record. You can start with the raw text.

    If you get stuck, you can refer to the provided solution code for each task, available in the solution folder.

    info> This lab experience was developed by the Pluralsight team using an internally developed AI tool. All sections were verified by human experts for accuracy prior to publications. However, content may still contain errors or inaccuracies, and we recommend independent verification.

    To report a problem or provide feedback, click here. Feedback may be used to improve accuracy in accordance with our Privacy Policy.

  2. Challenge

    Step 2: Capture and normalize employee text input

    Capturing raw text before you can trust it

    Every onboarding record starts as plain text an HR rep types at the console - a name, a department code, sometimes both padded with stray spaces or typed in whatever case felt natural at the time. Before you can compare or store that text, you need a place to declare it, read it in, and echo it back so the rep can confirm what was captured. That's the job of src/InputNormalizer.cs, starting with BuildEmployeeHeader. ## Trimming and case, together

    A header that faithfully echoes raw input still isn't safe to compare - ' eng' and 'ENG ' are the same department to a human but different strings to ==. The fix is normalization: trim the whitespace, then force a single consistent case, so every representation of the same value collapses to one string. NormalizeEmployeeText is where that happens, and every later comparison in this toolkit builds on it. ## Comparing normalized values

    With normalization in place, equality checks become straightforward - normalize both sides, then compare. IsMatchingDepartment puts that pattern to work directly, and it's the same pattern you'll reuse in Step 5 when a badge's department prefix has to be checked against an employee's stored department.

  3. Challenge

    Step 3: Slice and reshape badge codes without losing the original

    Slicing a badge code by position

    A badge code like ENG4821 packs two pieces of information into one string: a three-letter department prefix and a four-digit employee number, with no separator between them. C#'s Substring extracts a piece by position - Substring(start, length) or Substring(start) - using zero-based indexing, so the very first character sits at index 0. src/BadgeProcessor.cs starts by pulling the prefix off the front. ## Extracting what's left

    Once the prefix is isolated, the employee number is everything after it. The single-argument Substring(start) overload takes everything from that index to the end of the string, which is exactly the shape you need when the trailing portion can vary - not every badge number needs to be the same length. ## Reshaping text without touching the original

    Strings in C# are immutable: no method call ever changes the characters inside an existing string, it only ever hands you back a new one. That guarantee is exactly what makes masking safe - MaskEmployeeNumber builds a brand-new string with most digits hidden behind *, while the badgeCode parameter it was given keeps its original value for anything else that still needs it.

  4. Challenge

    Step 4: Model employees with fields and instance methods

    From strings to a modeled employee

    Cleaned, sliced text is still just text. src/Employee.cs turns it into something the rest of the system can reason about: a class with fields for Name, Department, BadgeCode, HireDate, and a CheckInCount, plus instance methods that read and update that state. The constructor is the first piece - it's what turns four loose values into one coherent object. ## Computing behavior from stored state

    Once an Employee holds its own HireDate, tenure isn't something you pass around separately - it's something the object can compute for itself on demand, from a date you supply. ComputeTenureYears uses DateTime subtraction to get a TimeSpan, then converts that elapsed time into whole years. ## Methods that change state, not just read it

    Not every instance method only reports on existing fields - some update them. CheckIn is that kind of method: each call should leave the object's state different from before, incrementing a running count and reflecting that new count in the message it returns.

  5. Challenge

    Step 5: Encapsulate behavior and assemble the onboarding tool

    Locking fields behind a public API

    So far, Employee's fields have been open to direct assignment from anywhere - convenient while you were building the class, but risky once other code depends on it: nothing stops a caller from setting Department to blank or garbage text. Encapsulation fixes that by making fields private and exposing change only through methods that validate first. UpdateDepartment is that validated entry point for one field. ## Assembling the pipeline

    With normalization, badge slicing, and a properly encapsulated Employee class all in place, src/OnboardingService.cs is where they finally meet. ProcessNewHire takes the four raw values an HR rep types in, runs them through InputNormalizer and BadgeProcessor, and returns one clean confirmation - the same shape of work you did by hand in Steps 2 and 3, now happening in a single call. ## Validating across objects before acting

    The last piece ties badge data back to the employee it belongs to: a check-in should only succeed if the badge's department prefix actually matches the employee's stored department. RegisterCheckIn combines BadgeProcessor.ExtractDepartmentPrefix and InputNormalizer.IsMatchingDepartment to guard the call to employee.CheckIn(), so a mismatched badge is reported, not recorded.

  6. Challenge

    Step 6: Run the application

    Every task is done, and each one was graded the moment you completed it. What you have not done yet is watch the whole application run at once -- which is the only place the pieces you wrote separately become a single working program.

    Start the application

    Open the Terminal tab and run:

    dotnet run --project src/Lab.csproj
    

    The program runs in the terminal and prints its output there. Every behaviour it shows is code you wrote in the previous steps, so read the output against what each task asked for -- that is the whole lab, working as one program. ### Run the checks yourself

    The lab ran each task's test for you as you went, but they are ordinary tests and you can rerun any of them whenever you like, one task at a time:

    bash runTest.sh Task_2_1
    

    Swap in the number of the task you want to check. Each failure names the task it belongs to, so the output tells you which step to go back to rather than which line to stare at. Two things worth trying before you finish: break something on purpose and watch the matching check fail, then put it back. Knowing what a failure looks like is worth as much as knowing what a pass looks like, and it costs you nothing here.

    When you are done, everything you wrote is still in the editor tabs -- the lab is yours to keep reading.

About the author

Pluralsight’s AI authoring technology is designed to accelerate the creation of hands-on, technical learning experiences. Serving as a first-pass content generator, it produces structured lab drafts aligned to learning objectives defined by Pluralsight’s Curriculum team. Each lab is then enhanced by our Content team, who configure the environments, refine instructions, and conduct rigorous technical and quality reviews. The result is a collaboration between artificial intelligence and human expertise, where AI supports scale and efficiency, and Pluralsight experts ensure accuracy, relevance, and instructional quality, helping learners build practical skills with confidence.

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight