Introduction to Object-Oriented Programming in C#
Vaibhav • September 10, 2025
Up to this point, we’ve explored the fundamentals of C# - from variables and control flow to methods and collections. Now we begin a new chapter that shifts our focus from procedural logic to a more powerful and scalable paradigm: Object-Oriented Programming, or OOP. This article introduces the core ideas behind OOP and sets the stage for the rest of Chapter 9, where we’ll explore classes, objects, encapsulation, and more.
Object-oriented programming is not just a feature of C# - it’s the foundation of how most modern C# applications are designed. Whether you’re building desktop software, web APIs, or mobile apps, understanding OOP is essential for writing clean, maintainable, and reusable code.
What is Object-Oriented Programming?
Object-oriented programming is a way of organizing code around objects - self-contained units that
combine
data and behavior. Instead of writing long sequences of instructions that
manipulate global variables,
you define types (called classes
) that model real-world entities or abstract
concepts.
These classes contain fields
(data) and methods
(behavior), and you create
objects
from them to perform tasks.
OOP helps you think in terms of “things” rather than “steps.” You model a problem domain using classes, and then interact with those classes through objects.
Why OOP Matters
As programs grow in size and complexity, procedural code becomes harder to manage. You end up with duplicated logic, tangled dependencies, and fragile code that breaks easily. OOP solves this by encouraging modular design: each class has a clear purpose, and changes to one part of the system don’t ripple unpredictably through others.
Here are some of the benefits of object-oriented design:
- Encapsulation: Hide internal details and expose only what’s necessary.
- Reusability: Write once, use many times - classes can be reused across projects.
- Maintainability: Easier to update and debug code when logic is grouped logically.
- Extensibility: Add new features without rewriting existing code.
Thinking in Objects
Let’s take a simple example. Suppose you’re building a system to manage books in a library. In procedural code,
you might use arrays and methods to store and manipulate book data. In OOP, you’d define a Book
class
that represents a book, and then create Book
objects to work with.
class Book
{
public string Title;
public string Author;
public int Year;
public void PrintInfo()
{
Console.WriteLine($"{Title} by {Author}, published in {Year}");
}
}
This class defines a blueprint for books. It has three fields - Title
, Author
,
and Year
- and one method, PrintInfo
, that
prints the book’s details.
You can now create actual book objects:
Book b1 = new Book();
b1.Title = "Clean Code";
b1.Author = "Robert C. Martin";
b1.Year = 2008;
b1.PrintInfo(); // Clean Code by Robert C. Martin, published in 2008
Each object stores its own data and can perform actions using its methods. This is the essence of OOP: bundling data and behavior together.
Classes vs Objects
A class is a definition - a template that describes what an object should look like and how it should behave. An object is an instance of a class - a real, usable thing created from that template.
Think of a class as a blueprint for a house, and an object as the actual house built from that blueprint. You can build many houses from the same blueprint, each with its own furniture and paint color.
In C#, you create objects using the new
keyword.
This allocates memory and calls the class’s constructor (we’ll cover constructors in the next article).
Fields and Methods
Fields are variables that belong to an object. They store the object’s state. Methods are functions that belong to an object. They define what the object can do.
In the Book
class above, Title
, Author
,
and Year
are fields. PrintInfo
is a method.
You can access fields and call methods using dot notation:
Book b2 = new Book();
b2.Title = "The Pragmatic Programmer";
b2.Author = "Andy Hunt";
b2.Year = 1999;
b2.PrintInfo();
This prints the book’s information using the method defined in the class. You can define as many methods as you need to model the behavior of your objects.
Access Modifiers
In C#, you control visibility using access modifiers. The most common ones are:
public
- accessible from anywhere.private
- accessible only within the class.protected
- accessible within the class and derived classes (we’ll cover inheritance later).
By default, fields and methods should be private
unless you have a reason to
expose them.
This protects your object’s internal state and prevents accidental misuse.
class Book
{
private string title;
private string author;
private int year;
public void SetDetails(string t, string a, int y)
{
title = t;
author = a;
year = y;
}
public void PrintInfo()
{
Console.WriteLine($"{title} by {author}, published in {year}");
}
}
Here, the fields are private, and you use a public method to set their values. This is a simple form of encapsulation - hiding internal details and exposing a controlled interface.
Designing Your Own Types
One of the biggest advantages of OOP is that you can design your own types to model any concept.
You’re not limited to built-in types like int
or string
.
If your program deals with cars, users, invoices, or planets - you can create classes for each of those.
For example, here’s a class that models a simple user:
class User
{
public string Username;
public bool IsAdmin;
public void Greet()
{
Console.WriteLine($"Welcome, {Username}!");
}
}
You can now create user objects and interact with them:
User u1 = new User();
u1.Username = "vaibhav";
u1.IsAdmin = true;
u1.Greet(); // Welcome, vaibhav!
This kind of modeling makes your code easier to understand and maintain. Instead of juggling multiple variables and functions, you group related logic into coherent units.
Objects Interacting with Each Other
In real applications, objects don’t exist in isolation - they interact with each other.
For example, a Library
class might contain a list of Book
objects.
You can use collections (like List<T>
) to store multiple objects and
define methods to manage them.
class Library
{
public List Books = new List();
public void AddBook(Book b)
{
Books.Add(b);
}
public void PrintAllBooks()
{
foreach (Book b in Books)
{
b.PrintInfo();
}
}
}
This example shows how one class can contain and manage objects of another class. You’re building a system where objects collaborate to perform tasks - a key idea in OOP.
You can nest objects, pass them as parameters, return them from methods, and store them in collections. This flexibility is what makes OOP so powerful.
Summary
Object-oriented programming is a paradigm that organizes code around objects - units that combine data and behavior. In this article, we introduced the core concepts of OOP in C#: classes, objects, fields, methods, and access modifiers. We saw how to model real-world entities using custom types, and how objects interact with each other to build systems.
Understanding OOP is essential for writing scalable and maintainable C# applications. As we continue through Chapter 9, we’ll explore more advanced features like constructors, encapsulation, properties, and object lifecycle. Each concept builds on the foundation laid here, so take time to experiment with your own classes and objects - it’s the best way to internalize these ideas.
In the next article, we’ll dive into Classes and Objects - how to define them properly, instantiate them, and use them effectively in your programs.