Мне нравится отделять свои определения от моих реализаций. У меня есть интерфейс Entity:Ограничение типа общего типа не выполняется в конкретной ситуации
public interface Entity<E> where E : Entity<E>
{
EntityId EntityId { get; }
bool ReadOnly { get; }
void FailIfReadOnly();
E Copy();
}
E является фактическим тип объекта, например, Заказчик:
public interface Customer : Entity<Customer>
{
}
У меня проблема является реализация FailIfReadOnly(): если ReadOnly == верно, то бросить EntityIsReadOnlyException.
public class EntityIsReadOnlyException<E> where E : Entity<E>
{
public EntityIsReadOnlyException(E entity)
: base(string.Format("Entity {0} is read only", entity.EntityId))
{
}
}
public class EntityImpl<E> : Entity<E> where E : Entity<E>
{
public EntityImpl(E other)
{
}
public bool ReadOnly
{
get;
protected set;
}
public void FailIfReadOnly()
{
if (! ReadOnly) throw new EntityIsReadOnlyException<E>(this);
}
}
throw new EntityIsReadOnlyException<E>(this);
вызывает ошибку компиляции:
The best overloaded method match for 'EntityIsReadOnlyException.EntityIsReadOnlyException(E)' has some invalid arguments
Argument '1': cannot convert from 'EntityImpl' to 'E'
я могу сделать:
EntityIsReadOnlyExcetion<Customer> exc = new EntityIsReadOnlyException<Customer>(customerImpl);
и даже:
Entity<E> entity = new EntityImpl<E>(this);
но не:
EntityIsReadOnlyException<E> exc = new EntityIsReadOnlyException<E>(this);
В обоих случаях E ограничивается подклассами Entity. Мой вопрос: почему я получаю эту ошибку компиляции? Это, наверное, что-то очень простое.
Какова цель 'where E: Entity' на интерфейсе? –
Это рекурсивное определение, не так ли? IE ограничение типа - это объект>? Возможно ли это? –
Spence
@marcgravell - обычно целью таких рекурсивных ограничений типа является реализация клона или копии в базовом классе, который может возвращать производный тип. – x0n