문제
어쩌면 나는 멍청하지만 ...
나는 가지고있다:
public interface IRequest
{
IList<IRequestDetail> Details { get; set; }
// stuff
}
public interface IRequestDetail
{
// stuff
}
나는 다음과 같이있다.
public class MyRequest : IRequest
{
IList<MyRequestDetail> Details {get; set; }
// stuff
}
public class MyRequestDetail : IRequestDetail
{
// stuff
}
작동하지 않습니다.
MyRequest는 ILEST의 IRQUESTDETAIL이 없기 때문에 인터페이스를 구현하지 않기 때문에 C#이 나에게 화를냅니다.
이제 변경하면 세부 사항이 IREQUESTDETAIL의 ILIST 인 경우 코드의 모든 곳에 MyRequestDetail에 캐스팅해야합니다 (공통 사항을 공유하지만 전문화하는 몇 가지 요청이 있습니다).
나는 왜 그것이 잘못되었는지 이해하지만 완전히 완전히 그렇지 않습니다!
해결책
문제는 세부 사항을 일반 목록으로 취급하고 IREQUESTDETAIL을 구현하도록 시행한다는 질문에 근거하여 생각합니다. 또한 구현 클래스에보다 구체적으로 입력되기를 원합니다. 이 경우 irquest를 일반으로 만들어야합니다.
이 시도:
public interface IRequest<T> where T : IRequestDetail
{
IList<T> Details { get; set; }
// stuff
}
public class MyRequest : IRequest<MyRequestDetail>
{
public IList<MyRequestDetail> Details {get; set; }
// stuff
}
이것은 당신을 위해 효과가 있습니다.
2017-03-17 편집
@Robert의 의견에 대한 답변에서 아래 확장 된 코드를 참조하십시오.
public interface IRequestDetail
{
}
public class MyRequestDetail : IRequestDetail
{
}
public interface IRequest<T> where T : IRequestDetail
{
IList<T> Details { get; set; }
// stuff
}
public class MyRequest<T> : IRequest<T>
where T : IRequestDetail
{
public IList<T> Details { get; set; }
// stuff
}
public class Consumer
{
public void MyFunction<T>(IRequest<T> request)
where T : IRequestDetail
{
}
public void Foo()
{
var test = new MyRequest<MyRequestDetail>();
MyFunction(test);
}
}
다른 팁
정확한. 마이클은 해결책이 있습니다. 문제는 조금 까다 롭습니다.
그것은 명백한 전환이 없다는 것입니다
IList<MyRequestDetail>
에게
IList<IRequestDetail>
그것은 당신이 다른 클래스 (예 : myRequestDetail2)를 기반으로하는 다른 객체를 추가 할 수 있음을 의미하기 때문에 두 번째 객체에 "myRequestDetail"이 아닙니다. 그리고 그것은 첫 번째에게는 불법입니다.
이것은 C#의 공분산 및 비정규로 인한 것입니다. 문제에 대한 매우 상세하고 명확한 설명이 있습니다 (많은 부분으로 나뉩니다) Eric Lippert의 블로그.