Generic queries and handlers without reflection
One objection I could raise is that your generic type constraint doesn't guarantee what you think it might guarantee. Eg. you could have:

// TSelf is actually not T of Self
public class HelloQuery : IQuery&lt;GoodbyeQuery, string&gt; 
{
}

// This one is fine
public class GoodbyeQuery: IQuery&lt;GoodbyeQuery, string&gt; 
{
}


In other words, TSelf doesn't actually have to be the T of the class itself. This is not horrible, especially since you seem to only be using the interface as metadata, but it can still lead to confusing results during dependency injection if you've accidentally screwed up a class definition.

However, as long as you're not a masochist and don't declare nonsensical types like this, there is nothing wrong with this. This is an established design pattern known as the curiously recurring template pattern.