이 인터페이스를 고려하시기 바랍니다있다 학생은 IInitialiazableEntity<IRepository>
이고 외관에는 t보다 전문화 된 실제 저장소가 있습니다. 그는 기본 IRepository
(즉, 그것은 IMySpecialRepository : IRepository
일 것입니다), IMySpecialRepository
을 캐스팅하고 엔티티의 Initialize
메서드에 전달할 수 있다는 것을 깨닫게 될 is
키워드는 있습니까? 아니면 그렇지 않으면 어떻게해야합니까?C#을 제네릭 키워드 공분산/contravariance 유형이 inferral
답변
현재 인스턴스가있는 경우 SomeFacade<IMySpecialRepository>
코드가 작동하지 않습니다.
두 가지 옵션이 있습니다. 하나는 Dan Bryant가 제공 한 답변이고 다른 하나는 IInitialiazableEntity<TRepository>
을 반공 변하게 만드는 옵션입니다. 될 것입니다
귀하의 인터페이스 선언 (제네릭 형식에 in
주의) :
public interface IInitialiazableEntity<in TRepository> where TRepository : class, IRepository
{
void Initialize(TRepository repository);
}
이것은 당신의 is
검사를 허용하고 contravariant 일반적인 사용시 IInitialiazableEntity<IRepository>
는 IInitialiazableEntity<IMySpecialRepository>
에 캐스트 할 수있는, 일을 캐스팅합니다.
제네릭의 공분산 및 Contravariance에 대한 자세한 내용은 here을 참조하십시오.
선생님, 모든 점에서 큰 차이가 있습니다. 내가 이런 질문을하지 않았 더라면 결코 이런 식으로 갈 수 없었을 것입니다. 공유해 주셔서 감사합니다. –
엔터티가 Student 유형이라고 가정하면 'is'는 false를 반환합니다. 이것은 학생이보다 구체적인 인터페이스 전문화를 구현하지 않기 때문입니다. 이 더 구체적인 인터페이스로 캐스팅 할 필요는 없습니다. 이것은 잘 작동합니다 :
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);
}
}
}
그러나 Student 엔티티는 기본 IRepository를 사용할 수 있지만 다른 엔티티는 IInitialiazableEntity를보다 전문화 된 저장소로 구현할 수 있으므로 지원해야합니다. –
그러나 상속의 상단은 외관에있는 TRepository가 될 것입니다. 어떤 엔티티도 외관보다 더 전문화 된 repo를 사용하지 않습니다. 또는 엔티티가 가장 전문화 된 repo로 초기화 가능한 것을 구현해야하고, 완료되면 true가 반환됩니다. 어떻게 생각하십니까? –
시도해 보셨습니까? 또한 IMySpecialRepository 및 IMySpecializedRepository는 무엇입니까? – ken2k
죄송합니다. 테스트해볼 수있는 해결책을 찾았지만 너무 급하게 보내고 있습니다. 그리고 그것은 다른 사람들에게 유용 할 것이라고 생각합니다 (제목/태그가 맞다면). –
@ ken2k 특별한 (ized) 저장소 (typo가 있었는데, 둘 다 똑같습니다, 나는 그것을 고쳤습니다) - 기본 IRepository를 상속받은 것입니다. –