It's hard to say, given that you only listed two ads, not how you use them. Is IdT another type parameter somewhere? (If it were a TId , it would suggest that it is - but the fact that you are using EntityT for another type parameter, contrary to conventions, suggests that perhaps IdT too ...)
Now, if IdT is actually Guid in your case, how should the compiler work, what do you mean Foo ? Other types related to EntityObject<Guid> may exist.
In short, you did not give us enough information to say something for sure, but it looks like you basically make unreasonable requirements on the compiler.
EDIT: Okay, here I guess what you have using the usual naming conventions:
public interface IRepository { TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId> } public abstract class EntityObject<TId> { public IdT id { get; set; } } public class Foo : EntityObject<Guid> {}
You want to do:
IRepository repository = GetRepositoryFromSomewhere(); Foo foo = repository.Get<Foo>(someGuid);
While you should be doing now:
Foo foo = repository.Get<Foo, Guid>(someGuid);
Yes, the compiler makes this a little harder for you than necessary. As many as 6 extra characters to keep the language simpler and type inference rules easier to understand.
Basically, type inference is all or nothing — either all type parameters are output, or none of them are. This simplifies the work, since you do not need to determine which ones are indicated and which are not. This part of the problem, and the other part is that you can only express restrictions on the parameters of the method type - you cannot:
class Repository<TEntity> { TEntity Get<TId>(TId id) where TEntity : EntityObject<TId> }
since this is a limitation of TEntity , not TId . Again, such things simplify type inference.
Now you can write:
Foo foo = repository.Get(someGuid).For<Foo>();
with the corresponding Get method and an additional interface. I think that personally, I would rather just use Get<Foo, Guid> .