Reputation: 12833
Given the interfaces and types below, I would like to have an interface for a PartyDao:
public interface IPartyDao<IdT> : IDao<Party<IdT>> where IdT : struct{}
I cannot do this because the compiler thinks that a Party is not convertible into an EntityWithTypedId. To look at the signature of a Party, it seems that Party IS an EntityWithTypedId and therefore s/b convertible into one.
Besides the fact that the compiler is always right, why is it right in this case? Is there a fix?
Much of the nastiness, at least aesthetically, comes from using IdT, but
// IdT is just the id, usually either an int or Guid
//
public interface IEntityWithTypedId<out TId> where TId : struct
{
TId Id { get; }
}
// base impl
public abstract class EntityWithTypedId<TId> : IEntityWithTypedId<TId> where TId:struct
{
//..
}
// Party *IS* of the right lineage
public class Party<IdT> : EntityWithTypedId<IdT> where IdT : struct
{
//..
}
//
public interface IDao<T, in IdT>
where T : EntityWithTypedId<IdT>
where IdT : struct
{
//..
}
Upvotes: 1
Views: 177
Reputation: 203819
Change your interface to:
public interface IPartyDao<IdT> : IDao<Party<IdT>, IdT>
where IdT : struct { }
And it will compile.
The code you posted here doesn't have a second generic argument passed to IDao
.
In order to get the error you're seeing you'd need to pass a type other than IdT
as the second generic argument. If you pass, say, an int
(to get the first compiler error to go away) then the error would be that you couldn't convert a Party<IdT>
to an EntityWithTypedId<int>
. The generic arguments of those types need to match (since they're neither covariant nor contravariant in their generic argument).
Upvotes: 5