2012-10-31 6 views
1

제네릭 형식 매개 변수에서 파생 될 수 없다는 것을 알고 있으며 허용 된 경우 발생하는 모든 문제를 이해합니다.제네릭 형식 매개 변수에서 파생되는 문제를 해결하려면

그래서 제 질문은, 어떻게이 문제를 해결합니까입니까?

public class Proxy<T> : T where T : CommonBaseClass 

내가 원하는 것 그 이유는 내가 이런 일을하는 것입니다 때우기 (그것을 할 수 없기 때문에 해결책이 아니다) 일부 중복 코드와 최적의 솔루션을 제거하려고 이것은 CommonBaseClass의 일부 메소드를 대체하는 것입니다. 여기

내 프로젝트에서 일부 실제 코드 예제입니다 : 모두 HttpWebClientProtocol에서 파생 SoapHttpClientProtocol에서 파생 ReportingService2010 & ReportExecution2005 클래스 위의 예에서

public class ReportingServiceProxy : ReportingService2010 
{ 
    protected override WebResponse GetWebResponse (WebRequest request) 
    { 
     WebResponse response = base.GetWebResponse(request); 
     // Do override stuff here 
     return response; 
    } 
} 

public class ReportingExecutionProxy : ReportExecution2005 
{ 
    protected override WebResponse GetWebResponse (WebRequest request) 
    { 
     WebResponse response = base.GetWebResponse(request); 
     // Do override stuff here 
     return response; 
    } 
} 

. 재정의 메서드 GetWebResponseGetWebRequest은 모두 HttpWebClientProtocol의 메서드보다 우선하며 동일합니다. 이 메소드들은 리팩터링하려고하는 코드 중복이 존재하는 곳입니다.

public abstract class SSRSReportBase<T> where T : new() 
{   
    protected T ssrs; 
    protected abstract void ServiceLogon(); 

    public SSRSReportBase() 
    { 
     ServiceLogon(); 
     // Do other common constructor work here. 
    } 
} 

// Implementation #1 
public class SSRSReportExecution : SSRSReportBase<ReportExecutionProxy> 
{ 
    protected override void ServiceLogon() 
    { 
     ssrs.LogonUser("LoginName", null, null); 
    } 

    // Create additional wrapper methods for ReportExecution2005 
} 

// Implementation #2 
public class SSRSReportingService : SSRSReportBase<ReportingServiceProxy> 
{ 
    protected override void ServiceLogon() 
    { 
     ssrs.LogonUser("LoginName", null, null); 
    } 

    // Create additional wrapper methods for ReportingService2010 
} 

내가 함께 온 유일한 해결책은 가능한 해결책이 아니다, 그래서 분명히 해결책이 아니다 : 완성도를 들어

, 여기에 내가 위의 코드를 구현하는 몇 가지 추가 코드입니다. 여기에 나쁜 코드는 다음과 같습니다

public class ReportProxy<T> : T where T : HttpWebClientProtocol, new() 
{ 
    protected override WebResponse GetWebResponse (WebRequest request) 
    { 
     WebResponse response = base.GetWebResponse(request); 
     return response; 
    } 
} 

// Implementation #1 
public class SSRSReportExecution : SSRSReportBase<ReportProxy<ReportExecution2005>> 
{ 
} 

// Implementation #2 
public class SSRSReportingService : SSRSReportBase<ReportProxy<ReportingService2010>> 
{ 
} 

질문 :중복 코드합니다 (GetWebRequestGetWebResponse 재정의를) 제거 그래서 내 질문은, 어떻게 코드가 같은 방식으로 리팩토링 할 수있다?

+0

그래서, 당신은 효과적으로 클래스 (X, Y)의 래퍼를 원하고 그래서 당신은 하나 개의 메소드를 호출 모두 X와 Y에 대한 동일한 효과를 얻을 수를 사용하십니까? 어쩌면 내가 원하는대로 혼란 스러울 수도 있습니다. – Tejs

+0

당신이하려는 것을 달성하기 위해 상속보다는 구성을 고려할 수 있습니까? 그러면 GetWebResponse에 대한 호출을받을 T의 private 인스턴스가 생깁니 까? – nieve

+0

나는 이것이 최적의 솔루션이라고 생각하고 있었다.내부의'T' 레퍼런스를 취해서 메소드를 통해 단순히 그것의 오퍼레이션을 기본'T' 구현체에 노출시킨다. – Tejs

답변

1

해결 방법은 제네릭을 전혀 사용하지 않고 공장 패턴을 사용하는 것입니다. BaseClassnew() 제약 조건이있는 일반 매개 변수를 갖는 대신 모두 BaseClass을 입력하고 new()에 대한 공장을 제공하십시오. 이는 완전한 기능을 갖춘 팩토리 클래스이거나 간단한 팩토리 델리 케이트 일 수 있습니다.

public interface IProtocolFactory 
{ 
    ProtocolBaseClass Create(); 
} 

public class SomeDerivedProtocolFactory : IProtocolFactory 
{ 
    public ProtocolBaseClass Create() 
    { 
     return new SomeDerivedProtocol(); 
    } 
} 

공장에서 초기화 코드를 추가 할 수도 있습니다.

public class ReportProxy 
{ 
    private IProtocolFactory _factory; 

    public ReportProxy(IProtocolFactory factory) 
    { 
     _factory = factory; 
    } 

    public void DoSomething() 
    { 
     ProtocolBaseClass protocol = _factory.Create(); 
     ... 
    } 
} 

대리인

private Func<ProtocolBaseClass> _createProtocol; 

    public ReportProxy(Func<ProtocolBaseClass> createProtocol) 
    { 
     _createProtocol= createProtocol; 
    } 

    public void DoSomething() 
    { 
     ProtocolBaseClass protocol = _createProtocol(); 
     ... 
    } 
+0

고마워요 - 이것은 제가 한 일입니다. 나는 일반 제네릭을 함께 정리하고 공용 패턴 (오버라이드)을 설명하기 위해 서비스의 인터페이스 및 부분 클래스와 함께 팩토리 패턴을 사용했다. 그럼, 해결책 : 제네릭 대신 부분 클래스 및 인터페이스를 사용하십시오. – Steve

관련 문제