A class in C# typically includes the following components:
- Fields: Variables that hold the state of the class.
- Properties: Special methods that provide a flexible mechanism to read, write, or compute the values of private fields.
- Methods: Functions that define the behavior of the class.
- Constructors: Special methods used to initialize objects of the class.
Type of Class | Description | Characteristics | Example |
---|---|---|---|
Concrete Class | A standard class that can be instantiated. | Can have fields, properties, methods, and constructors. | csharp public class Car { ... } |
Abstract Class | A class that cannot be instantiated and may contain abstract methods. | Can have both abstract methods (without implementation) and concrete methods. | csharp public abstract class Animal { public abstract void Speak(); } |
Static Class | A class that cannot be instantiated and can only contain static members. | All members must be static; cannot create an instance of the class. | csharp public static class MathUtilities { public static int Add(int a, int b) { ... } } |
Partial Class | A class definition that can be split across multiple files. | Allows for better organization of code, especially for large classes. | csharp public partial class Person { ... } // in another file public partial class Person { ... } |
Nested Class | A class defined within another class. | Can access the containing class's members, including private ones. | csharp public class OuterClass { public class InnerClass { ... } } |
Generic Class | A class that can operate with any data type specified at instantiation. | Uses type parameters (placeholders) to define class behavior. | csharp public class Box<T> { public void Add(T item) { ... } } |
Sealed Class | A class that cannot be inherited. | Prevents other classes from deriving from it. | csharp public sealed class FinalClass { ... } |
Friend Class | Not a specific C# concept, but in C++ allows access to private members of another class. C# uses internal access modifiers. | N/A | N/A |
Brief Explanation of Each Type:
Concrete Class: The most common type of class that can be instantiated and used directly.
Abstract Class: Used as a base class. It can define common behavior for derived classes but cannot be instantiated on its own.
Static Class: Useful for grouping utility functions or constants. Since it cannot be instantiated, all its members must be static.
Partial Class: Allows splitting class definitions into multiple files, which can be useful for large classes or when auto-generated code is involved.
Nested Class: A class defined within another class, which can be used to logically group classes that are only used in one context.
Generic Class: Enables the creation of classes that can work with any data type, promoting code reuse and type safety.
Sealed Class: Prevents inheritance, ensuring that the class cannot be extended. This is useful for security and design reasons.
Friend Class: While not a direct feature in C#, the concept exists in other languages like C++. In C#, the
internal
access modifier allows classes within the same assembly to access each other's members.
Example Code Snippets for Each Type:
Concrete Class:
csharp1public class Car 2{ 3 public string Make { get; set; } 4 public string Model { get; set; } 5}
Abstract Class:
csharp1public abstract class Animal 2{ 3 public abstract void Speak(); 4}
Static Class:
csharp1public static class MathUtilities 2{ 3 public static int Add(int a, int b) => a + b; 4}
Partial Class:
csharp1public partial class Person 2{ 3 public string Name { get; set; } 4}
Nested Class:
csharp1public class OuterClass 2{ 3 public class InnerClass 4 { 5 public void Display() => Console.WriteLine("Inner Class"); 6 } 7}
Generic Class:
csharp1public class Box<T> 2{ 3 private T content; 4 public void Add(T item) => content = item; 5}
Sealed Class:
csharp1public sealed class FinalClass 2{ 3 public void Show() => Console.WriteLine("This is a sealed class."); 4}
Access Modifiers in C#
Access Modifier | Description | Scope |
---|---|---|
public | The member is accessible from any other code in the same assembly or another assembly that references it. | Global scope; accessible from anywhere. |
private | The member is accessible only within the body of the class or struct in which it is declared. | Local scope; accessible only within the containing class or struct. |
protected | The member is accessible within its own class and by derived class instances. | Accessible in the containing class and derived classes. |
internal | The member is accessible only within files in the same assembly. | Assembly scope; accessible within the same assembly but not from outside it. |
protected internal | The member is accessible from the current assembly or from derived classes in another assembly. | Combination of protected and internal ; accessible within the same assembly or by derived classes. |
private protected | The member is accessible only within its own class and by derived class instances within the same assembly. | Accessible in the containing class and derived classes, but only within the same assembly. |
Example of Each Access Modifier
Here’s an example demonstrating each access modifier:
csharp1public class Example 2{ 3 // Public member 4 public string PublicField; 5 6 // Private member 7 private string PrivateField; 8 9 // Protected member 10 protected string ProtectedField; 11 12 // Internal member 13 internal string InternalField; 14 15 // Protected internal member 16 protected internal string ProtectedInternalField; 17 18 // Private protected member 19 private protected string PrivateProtectedField; 20 21 public Example() 22 { 23 // Accessing all fields within the constructor 24 PublicField = "I am public"; 25 PrivateField = "I am private"; 26 ProtectedField = "I am protected"; 27 InternalField = "I am internal"; 28 ProtectedInternalField = "I am protected internal"; 29 PrivateProtectedField = "I am private protected"; 30 } 31} 32 33// Derived class 34public class DerivedExample : Example 35{ 36 public void Display() 37 { 38 // Can access PublicField, ProtectedField, and ProtectedInternalField 39 Console.WriteLine(PublicField); 40 Console.WriteLine(ProtectedField); 41 Console.WriteLine(ProtectedInternalField); 42 43 // Cannot access PrivateField or PrivateProtectedField 44 // Console.WriteLine(PrivateField); // Error 45 // Console.WriteLine(PrivateProtectedField); // Error 46 } 47} 48 49// Another class in the same assembly 50public class AnotherClass 51{ 52 public void Show() 53 { 54 Example example = new Example(); 55 Console.WriteLine(example.PublicField); // Accessible 56 // Console.WriteLine(example.PrivateField); // Error 57 // Console.WriteLine(example.ProtectedField); // Error 58 Console.WriteLine(example.InternalField); // Accessible 59 // Console.WriteLine(example.ProtectedInternalField); // Accessible 60 // Console.WriteLine(example.PrivateProtectedField); // Error 61 } 62}
Explanation of the Example
- Public Field:
PublicField
can be accessed from anywhere. - Private Field:
PrivateField
can only be accessed within theExample
class. - Protected Field:
ProtectedField
can be accessed withinExample
and any derived classes (likeDerivedExample
). - Internal Field:
InternalField
can be accessed within the same assembly but not from outside. - Protected Internal Field:
ProtectedInternalField
can be accessed from derived classes and from anywhere within the same assembly. - Private Protected Field:
PrivateProtectedField
can only be accessed within theExample
class and in derived classes, but only if they are in the same assembly.
Static Members of C# Class
static members belong to the class itself rather than to any specific instance of the class. This means:
- There is only one copy of a static member, regardless of how many instances of the class are created.
- Static members can be accessed without creating an instance of the class.
- Static members can be initialized either at the point of declaration or in a static constructor.
Example: Demonstrating Static Members
Here’s a complete example that demonstrates the use of static variables and methods in a C# class.
csharpCopy code1using System; 2 3public class Employee 4{ 5 // Static variable to keep track of the number of employees 6 private static int employeeCount = 0; 7 8 // Instance variables 9 public string Name { get; set; } 10 public int ID { get; set; } 11 12 // Constructor 13 public Employee(string name, int id) 14 { 15 Name = name; 16 ID = id; 17 employeeCount++; // Increment the static employee count each time a new employee is created 18 } 19 20 // Static method to get the current employee count 21 public static int GetEmployeeCount() 22 { 23 return employeeCount; 24 } 25} 26 27// Usage 28public class Program 29{ 30 public static void Main() 31 { 32 Employee emp1 = new Employee("Alice", 1); 33 Employee emp2 = new Employee("Bob", 2); 34 Employee emp3 = new Employee("Charlie", 3); 35 36 // Accessing the static method without creating an instance 37 Console.WriteLine("Total Employees: " + Employee.GetEmployeeCount()); // Output: Total Employees: 3 38 } 39}
Explanation of the Example
Static Variable:
- The
employeeCount
variable is declared as static. This means that it is shared among all instances of theEmployee
class. There is only oneemployeeCount
regardless of how manyEmployee
objects are created.
- The
Instance Variables:
Name
andID
are instance variables, meaning each instance ofEmployee
will have its ownName
andID
.
Constructor:
- In the constructor, every time a new
Employee
object is created, the static variableemployeeCount
is incremented.
- In the constructor, every time a new
Static Method:
- The method
GetEmployeeCount
is static, allowing it to be called without needing an instance ofEmployee
. It returns the current count of employees.
- The method
Usage:
- In the
Main
method, threeEmployee
objects are created. After that, the static methodGetEmployeeCount
is called to print the total number of employees.
- In the
Static Initialization
You can also initialize static variables directly at the point of declaration. Here’s an example of that:
csharp1public class MathConstants 2{ 3 // Static variable initialized at the point of declaration 4 public static readonly double Pi = 3.14159; 5} 6 7// Usage 8public class Program 9{ 10 public static void Main() 11 { 12 // Accessing the static variable directly 13 Console.WriteLine("Value of Pi: " + MathConstants.Pi); // Output: Value of Pi: 3.14159 14 } 15}
Explanation of Static Initialization
Static Readonly Variable:
- The
Pi
variable is declared asstatic readonly
, meaning it can only be assigned at the time of declaration or in a static constructor. This is useful for constants that should not change.
- The
Accessing the Static Variable:
- The
Pi
variable can be accessed directly using the class name without creating an instance.
- The