I am building a entity Repository and I have an interface, IIdentifiable<T>
. So entities which are identified by Guids, for example, implement IIdentifiable<Guid> with public Guid Id { get; }
. So far, so good.
I have an interface of IRepository<T, TIdentifier> where T : IIdentifiable<TIdentifier>
.
It seems to me that the TIdentifier generic argument is redundant, because that already information is held in the generic argument of T. Is there any way I can have a cleaner implementation of IRepository, where I only have to specify T in my bus开发者_如何学Ciness code?
I'm after something like 'IRepository<T> where T : IIdentifiable<T.GenericArgs[0]>
.
I doubt this is possible, but just thought I'd ask. Maybe the new C# 4 stuff has something for this this?
There's no constraint on T
which requires it to be a generic. And there's nothing which prevents a class from implementing IIdentifiable<T1>
, IIdentifiable<T2>
, ... IIdentifiable<Tn>
, so even some syntax saying "the first argument of the IIdentifiable'1
interface implemented by T
" wouldn't be sufficient.
You could create an IIdentifiable
that has object Id { get; }
then have IIdentifiable<T> : IIDentifiable
with a generic Id property.
Then you can reduce the number of generic arguments to 1 like so:
IRepository<T> where T : IIdentifiable
In practice you would then use IRepository<X>
with X : IIdentifiable<Guid>
This assumes that your IRepository is mainly interested in the ability of T to have a key and isn't focused on the specific type of key.
You are asking to be able to specify a contraint, based on the assumption that type has already satisfied that contraint, putting the compiler into a logical paradox.
Also, your plan makes TIdentifier
unknown within IRepository
which, I assume it's going to need to know.
精彩评论