Reputation: 902
Please consider this interface:
public interface IInitialiazableEntity<TRepository> where TRepository : class, IRepository
{
void Initialize(TRepository repository);
}
This class (snippet):
public class SomeFacade<TRepository> where TRepository : class, IRepository
{
public void Add<TEntity>(TEntity entity) where TEntity : AbstractEntity
{
try
{
if (entity is IInitialiazableEntity<TRepository>)
(entity as IInitialiazableEntity<TRepository>).Initialize(this.Repository);
}
catch (Exception ex)
{
this.Logger.Error(ex);
}
}
}
And the entity:
public class Student : AbstractEntity, IInitialiazableEntity<IRepository>
{
void Initialize(IRepository repository) { ... }
}
Since the student is only IInitialiazableEntity<IRepository>
and the facade will have an actual repository which is more specialized than the basic IRepository
(i.e. it will be IMySpecialRepository : IRepository
), will the is
keyword realize that it can cast the IMySpecialRepository
and pass it to the Initialize
method of the entity? Or if not, how to do it?
Upvotes: 0
Views: 262
Reputation: 19426
Currently, if you had an instance SomeFacade<IMySpecialRepository>
the code will not work.
You have two options, one is the answer provided by Dan Bryant, the other is to make IInitialiazableEntity<TRepository>
contravariant.
Your interface declaration will become (note the in
on the generic type):
public interface IInitialiazableEntity<in TRepository> where TRepository : class, IRepository
{
void Initialize(TRepository repository);
}
This will allow your is
check and cast to work, as IInitialiazableEntity<IRepository>
can be cast to IInitialiazableEntity<IMySpecialRepository>
when using a contravariant generic.
See here for more information about Covariance and Contravariance in generics.
Upvotes: 1
Reputation: 27505
Assuming your entity is of type Student, the 'is' will return false; this is because Student doesn't implement the more specific interface specialization. You don't need to cast to this more specific interface, though. This should work just fine:
public class SomeFacade<TRepository> where TRepository : class, IRepository
{
public void Add<TEntity>(TEntity entity) where TEntity : AbstractEntity
{
try
{
if (entity is IInitialiazableEntity<IRepository>)
(entity as IInitialiazableEntity<IRepository>).Initialize(this.Repository);
}
catch (Exception ex)
{
this.Logger.Error(ex);
}
}
}
Upvotes: 1