static void SetObject(object obj) { }
static string GetString() { return ""; }
static void SetString(string str) { }
static void Main()
{
// Covariance. A delegate specifies a return type as object,
// but I can assign a method that returns a string.
Func<object> del = GetString;
    // Contravariance. A delegate specifies a parameter type as string,
    // but I can assign a method that takes an object.
    Action<string> del2 = SetObject;
    // But implicit conversion between generic delegates is not supported
until C# 4.0.
    Func<string> del3 = GetString;
    Func<object> del4 = del3; // Compiler error here until C# 4.0.
}
Future reading:
http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contrava
riance-faq.aspx