Class
Classes serve as the building blocks of software applications. A class encapsulates data (stored in fields) and behavior (defined by methods). In other words, the anatomy of the class is comprised of Data (represented by fields) and Behaviour(represented by methods/functions).
Example. How to declare class?
public class Customer
{
// Field
public string Name;
// Method
public void Promote()
{
// Method implementation
}
}
Object
An object represents a specific instance of a class. It is instantiated using the new operator.
Customer customer = new Customer();
// Or
var customer = new Customer();
Constructors
A constructor is a function invoked during the instantiation of a class. Constructors are utilized to initialize an object's initial state. It's advisable to define a constructor solely when an object necessitates initialization for it to function properly. Constructors that lack a return type, including void, should bear identical names to their respective classes.
Constructors can be overloaded, which means we can create methods with the same name but different types or numbers of parameters. The signature of a method includes the types and order of its parameters. We can use this keyword to switch control from one constructor to another.
public class Client
{
// Properties
public int ID;
public string FullName;
public List<Order> Purchases;
// Default constructor
public Client()
{
// Prepare the list for purchases
Purchases = new List<Order>();
}
// Constructor with an ID parameter
public Client(int id) : this()
{
// Set the client's ID
this.ID = id;
}
}
Methods
A method's signature includes details like how many parameters it has, what types they are, and the order they appear in. When we overload a method, we create multiple methods with the same name but different parameter setups. This helps users choose the right method for the data they want to give.
public class Point {
// Moves the point to a new position specified by x and y coordinates
public void Move(int x, int y) {}
// Moves the point to a new location specified by another Point object
// This is an overloaded version of the Move method
public void Move(Point newLocation) {}
}
We can use the 'params' keyword to let a method take different amounts of parameters.
public class Calculator {
// The Add method can receive a variable number of integer parameters
// thanks to the 'params' modifier
public int Add(params int[] numbers) {}
}
Fields
A field can be set up in two ways: during construction or right when it's declared. By initializing a field upon declaration, you ensure it's always set, regardless of which constructor is used.
// This Customer class automatically initializes the Orders list when declared.
public class Customer {
public List<Order> Orders = new List<Order>();
}
We add the 'read-only' modifier to make our code more reliable. When a field is marked as read-only, it must be set during declaration or in a constructor, and its value cannot be altered afterward. This prevents accidental changes to the field's value, which could lead to unexpected behavior. For instance, in the previous example with Orders, marking it as read-only ensures that its value remains unchanged, preventing accidental loss of Order objects stored in the list.
// This Customer class ensures that the Orders list cannot be changed after initialization.
public class Customer {
public readonly List<Order> Orders = new List<Order>();
}
Access Modifiers
In C#, we have 5 access modifiers: public, private, protected, internal, and protected internal. (Most common are public, private, and protected).
Access Modifier |
Description |
public |
Accessible everywhere |
private |
Accessible only from inside the class |
protected |
|
internal |
|
protected internal |
|
Access modifiers help conceal how a class works. Anything related to 'how' a class does its job should be private. This ensures that other parts of the code won't interfere with how the class works, making our code more reliable. If we change how a class works, we only need to update the class itself, not other parts of the code.
Properties
A property is a kind of class member that is used for providing access to fields of a class. It's a good idea to keep fields private and use public properties to access them. A property includes a 'get' method to fetch the field's value and a 'set' method to update the field with a new value.
public class Customer
{
private string _name;
// Property for accessing the _name field
public string Name
{
get { return _name; } // Retrieves the value of _name
set { _name = value; } // Sets the value of _name
}
}
If you don't have any specific logic in the get or set method, it's better to use an auto-implemented property. It automatically encapsulates a private field behind the scenes, saving you from manually creating one. Here's an example:
public class Customer
{
// Auto-implemented property for Name
public string Name { get; set; }
}
Indexers
An indexer is like a special property that lets you access elements of a list by their position (index).
If a class behaves like a list or collection, we can define an indexer property for it. This makes it easier to get or set items in the collection.
public class HttpCookie
{
// Indexer property allowing access to elements by key
public string this[string key]
{
get { /* logic to retrieve value */ }
set { /* logic to set value */ }
}
}