1

ジェネリック型パラメーターから派生することは不可能であり、許可された場合に発生するすべての複雑さを理解しています。

だから私の質問は、どうすればこれを回避できますか? 私はいくつかの重複したコードを排除しようとしていますが、私が思いついた最善の解決策 (実行できないため解決策ではありません) は、次のようなことです:

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

私がこれをしたい理由は、CommonBaseClass.

私のプロジェクトの実際のコード例を次に示します。

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;
    }
}

上記の例では、ReportingService2010&ReportExecution2005クラスは両方とも、SoapHttpClientProtocolwhich が から派生していますHttpWebClientProtocol。オーバーライド メソッドGetWebResponseと とGetWebRequestの両方のオーバーライド メソッド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>>
{
}

質問: 私の質問は、重複したコード (GetWebRequestおよびGetWebResponseオーバーライド) を削除するように、このコードをリファクタリングするにはどうすればよいですか?

4

1 に答える 1

1

解決策は、ジェネリックをまったく使用せず、ファクトリ パターンを使用することです。BaseClassおよびnew()制約を伴うジェネリック パラメーターを使用する代わりに。すべて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();
        ...
    }
于 2012-10-31T17:37:00.030 に答える