How do you make code reusable in C#?

To make code reusable in C#, there are several key approaches including interfaces, inheritance, generic classes, and static methods. Among these, interfaces are particularly powerful as they define a contract that multiple classes can implement, enabling polymorphism and flexible code design.

Interfaces define properties, methods, and events without providing implementations. The implementing classes must provide the actual functionality, ensuring a consistent structure across different implementations.

Syntax

Following is the syntax for declaring an interface −

public interface IInterfaceName {
   void MethodName();
   int PropertyName { get; set; }
}

Following is the syntax for implementing an interface −

public class ClassName : IInterfaceName {
   public void MethodName() {
      // implementation
   }
   
   public int PropertyName { get; set; }
}

Using Interfaces for Code Reusability

Interface names conventionally begin with "I" (capital i). Interface members are public by default and cannot have access modifiers.

Interface Implementation Pattern IShape display() Circle Rectangle Triangle All classes implement the same interface contract

Example

using System;

public interface IShape {
   void display();
   double GetArea();
}

public class Circle : IShape {
   private double radius;
   
   public Circle(double r) {
      radius = r;
   }
   
   public void display() {
      Console.WriteLine("This is a Circle with radius: " + radius);
   }
   
   public double GetArea() {
      return Math.PI * radius * radius;
   }
}

public class Rectangle : IShape {
   private double length, width;
   
   public Rectangle(double l, double w) {
      length = l;
      width = w;
   }
   
   public void display() {
      Console.WriteLine("This is a Rectangle with length: " + length + " and width: " + width);
   }
   
   public double GetArea() {
      return length * width;
   }
}

public class Program {
   public static void Main() {
      IShape[] shapes = { new Circle(5), new Rectangle(4, 6) };
      
      foreach (IShape shape in shapes) {
         shape.display();
         Console.WriteLine("Area: " + shape.GetArea());
         Console.WriteLine();
      }
   }
}

The output of the above code is −

This is a Circle with radius: 5
Area: 78.5398163397448

This is a Rectangle with length: 4 and width: 6
Area: 24

Using Generic Classes for Reusability

Generic classes allow you to write reusable code that works with different data types −

Example

using System;

public class GenericStack<T> {
   private T[] items;
   private int top;
   
   public GenericStack(int capacity) {
      items = new T[capacity];
      top = -1;
   }
   
   public void Push(T item) {
      if (top < items.Length - 1) {
         items[++top] = item;
      }
   }
   
   public T Pop() {
      if (top >= 0) {
         return items[top--];
      }
      return default(T);
   }
   
   public void Display() {
      Console.Write("Stack contents: ");
      for (int i = 0; i <= top; i++) {
         Console.Write(items[i] + " ");
      }
      Console.WriteLine();
   }
}

public class Program {
   public static void Main() {
      GenericStack<int> intStack = new GenericStack<int>(5);
      intStack.Push(10);
      intStack.Push(20);
      intStack.Display();
      
      GenericStack<string> stringStack = new GenericStack<string>(5);
      stringStack.Push("Hello");
      stringStack.Push("World");
      stringStack.Display();
   }
}

The output of the above code is −

Stack contents: 10 20 
Stack contents: Hello World 

Using Static Utility Methods

Static methods provide reusable functionality without needing object instances −

Example

using System;

public static class MathUtils {
   public static double CalculateCircleArea(double radius) {
      return Math.PI * radius * radius;
   }
   
   public static double CalculateRectangleArea(double length, double width) {
      return length * width;
   }
   
   public static bool IsPrime(int number) {
      if (number < 2) return false;
      for (int i = 2; i <= Math.Sqrt(number); i++) {
         if (number % i == 0) return false;
      }
      return true;
   }
}

public class Program {
   public static void Main() {
      Console.WriteLine("Circle area (radius 3): " + MathUtils.CalculateCircleArea(3));
      Console.WriteLine("Rectangle area (4x5): " + MathUtils.CalculateRectangleArea(4, 5));
      Console.WriteLine("Is 17 prime? " + MathUtils.IsPrime(17));
      Console.WriteLine("Is 15 prime? " + MathUtils.IsPrime(15));
   }
}

The output of the above code is −

Circle area (radius 3): 28.2743338823081
Rectangle area (4x5): 20
Is 17 prime? True
Is 15 prime? False

Comparison of Reusability Approaches

Approach Use Case Advantage
Interfaces Multiple classes need same contract Polymorphism, loose coupling
Generic Classes Same logic for different data types Type safety, performance
Static Methods Utility functions No object instantiation needed
Inheritance Shared behavior and structure Code sharing, method overriding

Conclusion

Code reusability in C# is achieved through interfaces for polymorphic behavior, generic classes for type-flexible logic, static methods for utilities, and inheritance for shared functionality. Interfaces are particularly powerful as they enable flexible design patterns and help create maintainable, extensible applications.

Updated on: 2026-03-17T07:04:35+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements