title: Generics to generalize WebRequests and parsing into custom objects in C#
body: <p>A bit of a architectural question. I am doing a lot of WebRequest:s in C# (Mono). Here's an example how one method that fetches "WorkFlowSchemes" are declared:</p>
  
  <pre><code>public void GetWorkFlowSchemes(
     Credientials credentials, 
     ServerDelegates.WorkFlowSchemesSuccessDelegate successDelegate, 
     ServerDelegates.ErrorDelegate errorDelegate)
  </code></pre>
  
  <p>Which then have "hardcoded" values for which url to fetch from, which callback the response it calling and in that callback: which type to parse to.</p>
  
  <p>I would like to make this method generic to not having to write X number of methods all very similar for each type of call I make. Instead I would like something like this:</p>
  
  <pre><code>public void GetCustomPath&lt;K&gt;(
      Credientials credentials,
      Path pathToFetch,
      ServerDelegate&lt;K&gt;.SuccessDelegate successDelegate, //Generic delegate to return different types of parsed result
      ServerDelegates.ErrorDelegate errorDelegate) // no need to be generic
  </code></pre>
  
  <p>where K is the type of the delegate to return i.e. <code>WorkFlowScemes</code> or WorkFlow.</p>
  
  <p>This work compiles fairly well, until the parsing. Previously I parsed it by doing this:</p>
  
  <pre><code>List&lt;WorkFlowScheme&gt; workFlowSchemeList = serverXmlParser.parseXmlToWorkFlowSchemeList(responseBody);
  </code></pre>
  
  <p>yet another hardcoded parsing method for WorkFlowList I would prefer to generalize. The <code>parseXmlToWorkFlowSchemeList</code> looks like this:</p>
  
  <pre><code>    public List&lt;WorkFlowScheme&gt; parseXmlToWorkFlowSchemeList (string xml)
      {
          XDocument doc = XDocument.Parse(xml);
          List&lt;WorkFlowScheme&gt; result = 
              (
                  from x in doc.Element("workflowschemeList").Elements("workflowscheme")
                  select new WorkFlowScheme().Setup(x)
                  ).ToList();
          return result;
      }
  </code></pre>
  
  <p><code>where .Setup(x)</code> is a help method stored in each type to convert and store the XElement values into strings in the current object. Here is where I got stuck. First I tried to make a generic method:</p>
  
  <pre><code>public List&lt;T&gt; parseXmlToCustomObject&lt;T&gt; (string xml, String root, String key)
  {
          XDocument doc = XDocument.Parse(xml);
          List&lt;T&gt; result = 
              (
                  from x in doc.Element(root).Elements(key)
                  select new T().Setup(x)
                  ).ToList();
          return result;
  }
  </code></pre>
  
  <p>"select new T.Setup(x)" does not work</p>
  
  <ul>
  <li>First since I cannot create "<code>new T()</code>" (Edit: already solved)</li>
  <li>Secondly cause the compiler wont know where to find the Setup method</li>
  </ul>
  
  <p>Any suggestions?</p>
  
  <p>I have also considered making all my objects to parse to a subclass of a "ServerObject" to more easy be able to call .Setup, but can't figure out how to merge that with generics.</p>
  
  <p>Edit: Here's what I got so far:</p>
  
  <pre><code>public void GetCustomListObject&lt;T&gt;(Account account, String path, RequestStateGen&lt;List&lt;T&gt;&gt;.SuccessDelegate successDelegate, ServerDelegates.ErrorDelegate errorDelegate)
          where T : ServerObject, new()
      {
          var request = getGetRequest(account, path);
  
          RequestStateGen&lt;List&lt;T&gt;&gt; state = new RequestStateGen&lt;List&lt;T&gt;&gt;();
          state.Request = request;
  
          IAsyncResult result =
              request.BeginGetResponse(new AsyncCallback(onGetWorkFlowSchemes), state);
  
          //setupTimeOut(result, state);
          string responseBody = extractResponseAndCallDelegateOnError(request, result, errorDelegate);
          if (responseBody != null)
          {
              List&lt;T&gt; parsedObject = serverXmlParser.parseXmlToCustomObject&lt;T&gt;(responseBody);
              if (parsedObject != null)
              {
                  successDelegate(parsedObject);
              }
          }
      }
  </code></pre>
  
  <p>And parsing method:</p>
  
  <pre><code>public List&lt;T&gt; parseXmlToCustomObject&lt;T&gt; (string xml)
          where T : ServerObject, new()
      {
          XDocument doc = XDocument.Parse(xml);
          List&lt;T&gt; result = 
              (
                  from x in doc.Element("workflowschemeList").Elements("workflowscheme")
                  select new T().Setup(x)
                  ).ToList();
          return result;
      }
  </code></pre>
  
  <p>Where ServerObject is a baseobject to all my custom object classes containing .Setup. The error I now get is on line "List result = " with error:</p>
  
  <pre><code>Cannot implicitly convert type `System.Collections.Generic.List&lt;xxxx.Core.Network.Objects.ServerObject&gt;' to `System.Collections.Generic.List&lt;T&gt;'
  </code></pre>