restrictive generics in c#

restrictive generics in c#
Discover how to enforce stricter type constraints and enhance type safety in your C# code using restrictive generics. This article delves into the concept of restrictive generics, demonstrating how to limit the usage of generic types to specific categories or interfaces. Learn how to define constraints that restrict the types allowable for a generic parameter, thereby preventing unintended usage and promoting cleaner, more predictable code.

Real-World Example: Numeric Calculator

Consider a scenario where you're building a calculator application that performs arithmetic operations on numeric values. To ensure type safety and prevent runtime errors, you want to restrict the calculator's generic methods to only accept numeric data types. Let's implement a NumericCalculator class with restrictive generics to achieve this:

using System;
using System.Collections.Generic;

public class NumericCalculator
{
    public static double CalculateAverage<T>(IEnumerable<T> numbers) where T : struct, IConvertible
    {
        if (!typeof(T).IsPrimitive || typeof(T) == typeof(bool))
        {
            throw new ArgumentException("Type must be a numeric type.");
        }

        double sum = 0;
        int count = 0;

        foreach (var number in numbers)
        {
            sum += Convert.ToDouble(number);
            count++;
        }

        if (count == 0)
        {
            throw new ArgumentException("Sequence contains no elements.");
        }

        return sum / count;
    }
}

class Program
{
    static void Main(string[] args)
    {
        List<int> integers = new List<int> { 1, 2, 3, 4, 5 };
        Console.WriteLine("Average of integers: " + NumericCalculator.CalculateAverage(integers));

        List<double> doubles = new List<double> { 1.5, 2.5, 3.5, 4.5, 5.5 };
        Console.WriteLine("Average of doubles: " + NumericCalculator.CalculateAverage(doubles));

        // This will cause a compile-time error because strings are not numeric types
        // List<string> strings = new List<string> { "1", "2", "3", "4", "5" };
        // Console.WriteLine("Average of strings: " + NumericCalculator.CalculateAverage(strings));
    }
}

In this example, the `NumericCalculator` class demonstrates restrictive generics by enforcing constraints (`where T : struct, IConvertible`) to restrict the generic type parameter `T` to numeric types only. Attempting to use non-numeric types will result in compile-time errors, ensuring type safety and preventing unintended usage. This illustrates how restrictive generics can help enforce type constraints and promote robustness in your C# codebase.

Post a Comment

0 Comments