Q:

В чем смысл контрвариантности параметров?

Доброго времени суток! Хочу задать такой вопрос: в чем смысл при контрвариантности параметров? Ну вот с ковариантностью возвращаемых значений вроде как все понятно/ Например есть такой код:
FooChild Method()
{        
    return new FooChild();
}

delegate Foo SomeDel();

// ..,

SomeDel del = Method;

и все прекрасно работает из-за ковариантности возвращаемых значений, потому что делегат SomeDel возвращает тип Foo, но этому делегату можно присвоить метод Method который возвращает производный от Foo тип FooChild, так как везде где можно использовать возвращаемое значение Foo логично что можно использовать и FooChild. С этим все понятно и все работает. Но непонятно с контрвариантностью. Например есть такой код:
delegate void SomeDel(Foo foo);

void Method(FooChild foo)
{
    Console.WriteLine(foo);        
}    

// ....

SomeDel del = Method; // ОШИБКА!!!

Почему возникает эта ошибка? Ведь вроде бы раз делегает требует параметр Foo то по идее он должен быть доволен, получив параметр FooChild так как FooChild является также и Foo. В чем подвох? 

A:

Ведь вроде бы раз делегает требует параметр Foo то по идее он должен быть доволен, получив параметр FooChild так как FooChild является также и Foo.

Метод требует параметр FooChild. Через делегат ему может быть передан просто Foo, который не является FooChild.
Предположим что ошибки компиляции не было. Что выведет следующий код?
delegate void SomeDel(Foo foo);

void Method(FooChild foo)
{
    Console.WriteLine(foo.SomePropertyInChildOnly);        
}

SomeDel del = Method; 

del(new Foo());

