2017-11-19 9 views
-1

내 인터페이스 (의 일부) :인터페이스 매개 변수 제약

public interface IRepository 
{ 
    Task<T> Insert<T>(T item) where T : class, ISyncable; 
} 

내 구현 : TableOperation.Insert 필요가 ITableEntity을 할 수 있기 때문에

public class TableStorageRepository: IRepository 
{ 
    public async Task<T> Insert<T>(T item) where T: class, ISyncable 
    { 
     TableOperation.Insert(item); 
    } 
} 

내 구현은 ISyncable

뿐만 아니라 작동하지 않습니다

Task<T> Insert<T>(T item) where T : class, ISyncable, ITableEntity; 내 인터페이스를 업데이트 할 수 없습니다. 다른 IRepository 구현이 작동하지 않기 때문입니다. 이자형.

내 구현 매개 변수 제약 ITableEntity을 추가 할 수 있습니다 다음 제약 조건은 다음과 같은 오류가 발생 더 이상 인터페이스 제약 조건과 일치하지 않기 때문에 : 매개 변수 유형에 대한

"제약 'T '방법 중 ... "

이 문제를 해결할 우아한 방법이 있습니까?

+1

별도의 인터페이스/메소드를 만들 수 없으면 가능한 런타임 오류가 발생하여 캐스팅합니다. –

+1

런타임시'itemStatusReposity'에서'item' 유형을 확인한 다음 전달 된 객체가 'ITableEntity'를 구현하지 않으면'ArgumentException' ... – Michael

+0

간격을 메우는 것이 가능할까요? 구현 세부 정보 숨기기? 당신은'ISyncable'을 구현 한 클래스를 받아들이고 내부적으로 차이를 처리한다는 것을 의미합니까? –

답변

0

IMHO 설정이 잘못되었습니다. Liskov substitution principle을 깨고 있습니다.

IRepository 인터페이스는 계약을 정의합니다. 이 계약에는 TISyncable이고 참조 유형 인 한 T을 삽입 할 수 있다고 나와 있습니다.

클래스 TableStorageRepository은 계약이입니다. ISyncable을 처리 할 수 ​​없으며 ITableEntity 만 처리 할 수 ​​있습니다. 그것은 살아갈 수없는 인터페이스를 구현하는 사업이 없으므로 그렇게하지 마십시오.

지저분한 런타임 유형 검사 등으로이 문제를 해결할 수 있지만 해킹이 부족합니다. 귀하의 빌딩 블록은 나쁘기 때문에 귀하가 만든 빌딩 블록은 모두 최상의 상태가됩니다.

이 작업을 피할 수없는 효과적인 완화 전략 중 하나는 특정 작업의 유효성을 소비자에게 알려주는 인터페이스를 인터페이스에 정의하는 것입니다. 즉, 인터페이스를 수정할 수 없다는 말을하는 것입니다. 그래서 이것은 선택 사항이 아닙니다.

+0

내가 말했듯이 여기서 요점을 놓치고 있다고 생각합니다. 이상적입니다. 작업 (T 항목)을 입력하십시오. 여기서 T : class, ISyncable, ITableEntity; 하지만 안타깝게도 ITableEntity를 추가 할 수 없기 때문에 다른 저장소가 손상 될 수 있습니다. TableStorage의 경우 ISyncable이 필요하지만 ITableEntity가 필요합니다. 나는 CanInsert를 추가 할 수 있었지만, 없이는하지 않고 싶었습니다. 나는 인터페이스를 수정할 수 없다고 결코 말하지 않았습니다. 어쨌든, 통찰력/코멘트/답변 주셔서 감사합니다! – Niels

+0

@Niels 나는 그 요점을 놓치고 싶지 않다. 클래스가 실제로 구현할 수없는 인터페이스를 구현하도록 시도하고 있습니다. 모든 'ISyncable'이 'ITableEntity'입니다. 당신이 경험하고있는 것처럼 이것은 좋은 상황이 아니며, 타입 시스템이 당신을 도우려는 것이 아니라 당신과 싸우고 있습니다. 때로는 호출을 성공할 수있는 방법을 사용자에게 제공 할 수있는 방법을 사용자에게 제공하는 다른 선택 사항이 없습니다. [예외적 인 경우를 피하려면] 최선책입니다 (https://blogs.msdn.microsoft. com/ericlippert/2008/09/10/vexing-exceptions /) :'System.IO.Stream'은'CanSeek'을 사용한 전형적인 예입니다. – InBetween

+0

@Neils 'ITableEntity'가'ISyncable'을 구현했다는 것이 혼란 스러울 수도 있습니다. 그게 아니라면 당신은 더 나쁜 상황에 처해 있습니다. – InBetween