Back to results for “Generics”
C# › Delegates, Events & Lambdas

How do delegate covariance and contravariance work with method group conversions in C#?

Advanced

Answer

C# allows a method to be assigned to a delegate type even if the method's RETURN TYPE is more derived (covariance) than the delegate's declared return type, or its PARAMETER TYPES are less derived / more general (contravariance) than the delegate's declared parameter types — reflecting that a method returning something MORE specific, or accepting something MORE general, can always safely stand in.
public delegate object Factory(); // expects something returning 'object'
string CreateString() => "hello"; // returns a MORE derived type (string)
Factory factory = CreateString; // OK: covariant return type match

public delegate void Handler(string s);
void HandleObject(object o) => Console.WriteLine(o); // accepts a LESS derived type
Handler handler = HandleObject; // OK: contravariant parameter type match
Real-world example Assigning an existing utility method to a delegate type without needing an exact, literal signature match.

Common follow-ups: How does this delegate variance relate to the similar covariance/contravariance rules for generic interfaces like IEnumerable<out T>?