Co-variance and contra-variance have always been two terms for me that made me pause. Neither are hard to understand and we often use what they mean instinctively in object-oriented programming. However, before today if you were to ask me what they were I would have to give you an example. For some reason, a clear, concise definition escaped me.
Then today I read a blog post on C# v4.0 on the Intel website that summed it up in one of those "ah ha" and "duh" moments.
Co-variance is when you treat something more derived as something less derived
Contra-variance is when you treat something less derived as something more derived
And the examples (not designed to model anything real) are easy:
// co-variance
private void DoSomething(object[] objects) { ... }
string[] myStrings = new string[] { "a", "b", ... };
DoSomething(myStrings);
// contra-variance
private void DoSomething(MyConcreteObjectA a) { ... }
private void DoSomething(MyConcreteObjectB b) { ... }
private MyObjectBase CreateObject() { ... }
MyObjectBase newObject = CreateObject();
DoSomething(newObject);