C#
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C#
-
Section 4: Working with Data
-
Section 5: Error Handling
-
Section 6: Delegates and Events
-
Section 7: Async Programming
-
Section 8: More Language Features
-
Section 9: File I/O and Serialization
-
Section 10: Networking in .NET
-
Section 11: The .NET Ecosystem
-
Section 12: Memory and Performance
-
Section 13: Concurrency Beyond Async
-
Section 14: Reflection and Attributes
-
Section 15: Testing and Best Practices
-
Section 16: Design Patterns in C#
-
Section 17: Standard Library Deep Dive
-
Section 18: Data Structures and Algorithms in C#
-
Section 19: GUI and Desktop Development Overview
-
Section 20: Practical Projects
-
Section 21: More Practice Exercises
-
Section 22: More Standard Library and Text Processing
-
Section 23: More Design Patterns
-
Section 24: More Projects
-
Section 25: Interview Practice
-
Section 26: C# Keywords Reference (Modifiers)
-
Section 27: C# Keywords Reference (Statements)
-
Section 28: C# Keywords Reference (Operators)
-
Section 29: BCL: System.Collections.Generic
-
Section 30: BCL: System.Linq
-
Section 31: BCL: System.Threading
-
Section 32: BCL: System.IO
-
Section 33: BCL: System.Text and System.Text.Json
-
Section 34: BCL: System.Net.Http
-
Section 35: C# Language Specification Topics
-
Section 36: More Practice Exercises
-
Section 37: More Async Patterns
-
Section 38: More BCL: System.Reflection and System.Diagnostics
-
Section 39: Nullable Reference Types In Depth
-
Section 40: C# Records and Pattern Matching In Depth
-
Section 41: Dependency Injection Deep Dive
-
Section 42: More Interview and Whiteboard Practice
19: Classes, Objects, and Constructors
Imagine you're an architect. You spend weeks drawing up a detailed blueprint for a house. That blueprint isn't a house itself—you can't sleep in it, you can't cook in the kitchen, and it doesn't take up any physical space in a neighborhood. It's just a set of instructions and specifications. However, once you have that blueprint, you can use it to build ten, fifty, or a thousand identical houses. Each individual house is a real, physical thing that exists in the world, but they all follow the rules laid out in that one blueprint.
In C#, we use this exact logic to organize our data. Here is how that maps to the code we're about to write:
- The Blueprint is the Class: This is where you define what a "thing" is and what it can do.
- The House is the Object (or Instance): This is the actual piece of memory created when you use that class.
- The Construction Process is the Constructor: This is the specific logic that runs the moment you "build" the object, ensuring it starts its life with the right values.
Defining the Blueprint
Let's move away from houses and build something for a game. I want to create a GameCharacter. Instead of creating separate variables for every single character's name and health, I'll wrap them into a class. This tells C#, "Every time I make a GameCharacter, it must have these specific traits."
public class GameCharacter
{
public string Name;
public int Health;
public int Level;
// This is the Constructor
public GameCharacter(string name, int health, int level)
{
Name = name;
Health = health;
Level = level;
}
}
Notice that the constructor—the method with the exact same name as the class—doesn't have a return type (not even void). I've seen a lot of beginners try to add void there, but that actually turns it into a regular method, and C# will stop treating it as the initialization logic. The constructor's only job is to take the incoming values and assign them to the class's fields.
Bringing the Code to Life
Now that we have our blueprint, we can actually "instantiate" (that's just a fancy word for "create") some characters. We do this using the new keyword. This is the moment the blueprint becomes a real object in your computer's memory.
// We are using the blueprint to create two distinct objects
GameCharacter playerOne = new GameCharacter("Aragorn", 100, 1);
GameCharacter playerTwo = new GameCharacter("Legolas", 80, 1);
Console.WriteLine($"Player 1 is {playerOne.Name} with {playerOne.Health} HP.");
Console.WriteLine($"Player 2 is {playerTwo.Name} with {playerTwo.Health} HP.");
I want you to realize that playerOne and playerTwo are completely independent. If Aragorn takes damage and his health drops to 50, Legolas is still sitting pretty at 80. They both share the same structure (the class), but they hold different state (the data).
Why Bother with Constructors?
You might be wondering why we don't just create the object and then set the variables one by one. You could, but it's dangerous. If I have a UserAccount class, I probably shouldn't allow an account to exist without an email address. By putting that requirement in the constructor, I'm forcing whoever uses my class to provide that data upfront. It's a way of guaranteeing that your objects are "valid" from the very first millisecond they exist.
📋 Practical Task
Building a Virtual Garage for Classic Cars
It's time to put this into practice. You need to create a system to track a collection of classic cars. Follow these requirements:
- Create a class called
ClassicCar. - Give it three public fields:
Make(string),Model(string), andYear(int). - Create a constructor for the
ClassicCarclass that requires all three values to be passed in during instantiation. - In your
Mainmethod, instantiate two different car objects (for example, a 1967 Mustang and a 1963 Corvette). - Print a sentence for each car to the console that looks like this: "The 1967 Ford Mustang is a beauty!"
There are no comments for now.