0

アーキテクチャに関する少しの質問。私はC#(Mono)で多くのWebRequestを実行しています。「WorkFlowSchemes」をフェッチする1つのメソッドがどのように宣言されるかの例を次に示します。

public void GetWorkFlowSchemes(
   Credientials credentials, 
   ServerDelegates.WorkFlowSchemesSuccessDelegate successDelegate, 
   ServerDelegates.ErrorDelegate errorDelegate)

次に、どのURLからフェッチするか、どのコールバックを呼び出すか、そのコールバックでどのタイプを解析するかについて、「ハードコードされた」値があります。

このメソッドを汎用的にして、呼び出しのタイプごとにX個のメソッドをすべて非常によく似たものにする必要がないようにします。代わりに私はこのようなものが欲しいです:

public void GetCustomPath<K>(
    Credientials credentials,
    Path pathToFetch,
    ServerDelegate<K>.SuccessDelegate successDelegate, //Generic delegate to return different types of parsed result
    ServerDelegates.ErrorDelegate errorDelegate) // no need to be generic

ここで、Kは、返されるデリゲートのタイプ、つまりWorkFlowScemesWorkFlowです。

この作業は、解析するまでかなりうまくコンパイルされます。以前、私はこれを行うことによってそれを解析しました:

List<WorkFlowScheme> workFlowSchemeList = serverXmlParser.parseXmlToWorkFlowSchemeList(responseBody);

WorkFlowListのさらに別のハードコードされた解析方法を一般化したいと思います。このparseXmlToWorkFlowSchemeListように見えます:

    public List<WorkFlowScheme> parseXmlToWorkFlowSchemeList (string xml)
    {
        XDocument doc = XDocument.Parse(xml);
        List<WorkFlowScheme> result = 
            (
                from x in doc.Element("workflowschemeList").Elements("workflowscheme")
                select new WorkFlowScheme().Setup(x)
                ).ToList();
        return result;
    }

where .Setup(x)XElement値を現在のオブジェクトの文字列に変換して格納するために、各タイプに格納されているヘルプメソッドです。これが私が行き詰まったところです。最初に私は一般的なメソッドを作ろうとしました:

public List<T> parseXmlToCustomObject<T> (string xml, String root, String key)
{
        XDocument doc = XDocument.Parse(xml);
        List<T> result = 
            (
                from x in doc.Element(root).Elements(key)
                select new T().Setup(x)
                ).ToList();
        return result;
}

「selectnewT.Setup(x)」が機能しない

  • まず、 " new T()"を作成できないため(編集:既に解決済み)
  • 次に、コンパイラがSetupメソッドの場所を認識しないようにします。

助言がありますか?

また、すべてのオブジェクトを「ServerObject」のサブクラスに解析して、.Setupをより簡単に呼び出せるようにすることも検討しましたが、それをジェネリックスとマージする方法がわかりません。

編集:これが私がこれまでに得たものです:

public void GetCustomListObject<T>(Account account, String path, RequestStateGen<List<T>>.SuccessDelegate successDelegate, ServerDelegates.ErrorDelegate errorDelegate)
        where T : ServerObject, new()
    {
        var request = getGetRequest(account, path);

        RequestStateGen<List<T>> state = new RequestStateGen<List<T>>();
        state.Request = request;

        IAsyncResult result =
            request.BeginGetResponse(new AsyncCallback(onGetWorkFlowSchemes), state);

        //setupTimeOut(result, state);
        string responseBody = extractResponseAndCallDelegateOnError(request, result, errorDelegate);
        if (responseBody != null)
        {
            List<T> parsedObject = serverXmlParser.parseXmlToCustomObject<T>(responseBody);
            if (parsedObject != null)
            {
                successDelegate(parsedObject);
            }
        }
    }

そして解析方法:

public List<T> parseXmlToCustomObject<T> (string xml)
        where T : ServerObject, new()
    {
        XDocument doc = XDocument.Parse(xml);
        List<T> result = 
            (
                from x in doc.Element("workflowschemeList").Elements("workflowscheme")
                select new T().Setup(x)
                ).ToList();
        return result;
    }

ここで、ServerObjectは、.Setupを含むすべてのカスタムオブジェクトクラスのベースオブジェクトです。私が今得ているエラーは、「List result ="」の行にエラーがあります:

Cannot implicitly convert type `System.Collections.Generic.List<xxxx.Core.Network.Objects.ServerObject>' to `System.Collections.Generic.List<T>'
4

2 に答える 2

4

すべてのクラスにパブリックパラメーターレスコンストラクターがある場合は、に制約where T : new()を追加できますparseXmlToCustomObject。これにより、最初のエラーが取り除かれます。

2番目のエラーを取り除くには、Setupメソッドを含むインターフェイスまたは基本クラスを作成し、すべてのクラスにこのインターフェイスを実装させるか、この基本クラスから派生させて、別の制約として追加する必要がありますwhere T : ISetupable, new()(名前はご容赦ください)

その場合、メソッドは次のようになります。

public List<T> parseXmlToCustomObject<T> (string xml, String root, String key)
    where T : ISetupable, new()
{
        XDocument doc = XDocument.Parse(xml);
        List<T> result = 
            (
                from x in doc.Element(root).Elements(key)
                select new T().Setup(x)
                ).ToList();
        return result;
}

すべてのクラスにパブリックパラメーターのないコンストラクターがあることを確認できない場合は、オブジェクトを作成するためにファクトリに頼る必要があります。

于 2013-02-19T09:57:51.750 に答える
2

の新しいインスタンスを作成するには、ジェネリックメソッドに制約を指定する必要がありますT

public List<T> parseXmlToCustomObject<T> (string xml, String root, String key) where T : new(){
[...]
}

2番目の質問の[編集]Setup() :メソッドとジェネリックメソッドへの別の制約を 持つ基本クラスまたはインターフェイスが必要です。

メソッドBaseClassを持つ基本クラスがあるとしましょう。Setup()

public List<T> parseXmlToCustomObject<T> (string xml, String root, String key) where T : BaseClass, new(){
[...]
}
于 2013-02-19T09:58:52.877 に答える