Skip to main content
A generic delegate is a strongly-typed reference to a method that utilizes one or more type parameters in its signature. By deferring the specification of parameter types or return types until instantiation, generic delegates provide type safety and structural reusability without requiring multiple distinct delegate declarations for different data types.

Custom Generic Delegate Declaration

A custom generic delegate is defined using angle brackets (<>) to specify type parameters. These parameters can be applied to the method’s return type, its input parameters, or both.

Instantiation, Assignment, and Invocation

Generic delegates can be instantiated and assigned using lambda expressions, anonymous methods, or method groups. Once assigned, they are invoked using standard method invocation syntax.

Built-in Generic Delegates

The .NET Base Class Library (BCL) provides three primary families of generic delegates, which eliminate the need to declare custom generic delegates in most scenarios:
  1. Action<T> Encapsulates a method that takes up to 16 input parameters and returns void. The delegate itself accepts up to 16 generic type parameters corresponding to the types of those input parameters.
  2. Func<T, TResult> Encapsulates a method that takes up to 16 input parameters and returns a value. The delegate supports up to 17 generic type parameters total: up to 16 for the input parameters, plus 1 for the return type (TResult). The return type is always the final type parameter in the signature.
  3. Predicate<T> Encapsulates a method that defines a set of criteria and determines whether the specified object meets those criteria. It accepts exactly one generic type parameter for its single input parameter and always returns a bool.

Variance in Generic Delegates

Generic delegates support covariance and contravariance for reference types, declared using the out and in contextual keywords.
  • Covariance (out): Applied to return types. It permits a delegate to return a more derived type than the one specified by the generic type parameter.
  • Contravariance (in): Applied to input parameters. It permits a delegate to accept parameters of a less derived (more generic) type than the one specified by the generic type parameter.

Type Constraints

Generic delegates support type constraints using the where clause. This restricts the kinds of types that can be substituted for the type parameters during instantiation, ensuring the delegate only operates on types that fulfill specific contracts (e.g., interfaces, base classes, or reference/value type requirements).
Tired of Poor C# Skills? Fix That With Deep Grasping!Learn More