public abstract class SomeBaseClass {}
public class SomeSpecificClass: SomeBaseClass {
public int propertyA;
public string propertyB;
}
public delegate void Callback<T>(T data);
public class Foo {
void MethodA <T> (Callback<T> theInstance) where T: SomeBaseClass {
MethodB(theInstance);
}
void MethodB(Callback<SomeBaseClass> theInstance) {
}
void MethodC() {
Callback<SomeSpecificClass> cb = (data) => {};
MethodA(cb);
}
void MethodD <T> (T theInstance) where T: SomeBaseClass {
MethodE(theInstance);
}
void MethodE (SomeBaseClass theInstance) {
}
}
Produces the error in MethodA:
Argument 1: cannot convert from 'Callback<T>' to 'Callback<SomeBaseClass>' [Assembly-CSharp]
Callback<T> theInstance
But MethodD works fine passing its instance to MethodE
Why can't I pass the generic Callback<T> instance in MethodA to argument of type Callback<SomeBaseClass> in MethodB when I'm specifiying the constraint that T extends SomeBaseClass

Basically, you can't do this because it's not safe.
Suppose we have a concrete class derived from SomeBaseClass:
public class SomeOtherSpecificClass {}
Suppose we change your MethodB to:
void MethodB(Callback<SomeBaseClass> theInstance)
{
theInstance(new SomeOtherSpecificClass());
}
That should compile, right? After all, you're just passing a SomeOtherSpecificClass into a Callback<SomeBaseClass>, which should be fine.
Then if I call MethodA like this:
Callback<SomeSpecificClass> callbcak = data => Console.WriteLine(data.propertyA);
MethodA(callback);
... then if all of that were allowed, we'd be passing a SomeOtherSpecificClass into a delegate expecting a SomeSpecificClass.
Your MethodD and MethodE examples are fine, because MethodE can only use members of SomeBaseClass... but a Callback<SomeSpecificClass> really requires a SomeSpecificClass, so you can't just treat it as if it were a method accepting a SomebaseClass.
To show this more simply:
// This is valid...
string text = "";
object obj = text;
// This isn't...
Action<string> stringAction = text => Console.WriteLine(text.Length);
Action<object> objectAction = stringAction;
// ... because it would allow this:
objectAction(new object());
See more on this question at Stackoverflow