title: How can I refactor this C# code currently using Dictionarys to have even less redundancy and be more typesafe?
body: <p>Because of business decisions which are above my paygrade, I need to parse and merge multiple XML files.</p>
  
  <p>In order to cut down on redundant code, I have this map:</p>
  
  <pre><code>        private static readonly Dictionary&lt;string, Type&gt; listTypeByFileName = new Dictionary&lt;string, Type&gt; {
              {"a.xml", typeof(List&lt;A&gt;)},
              {"b.xml", typeof(List&lt;B&gt;)},
              {"c.xml", typeof(List&lt;C&gt;)},
              {"d.xml", typeof(List&lt;D&gt;)},
              // etc.
          };
  </code></pre>
  
  <p>Because how this map gets used, after downloading and parsing all the XMLs, the result is of type <code>Dictionary&lt;string, object&gt;</code> where the <code>key</code> is the same as the keys in the above map and the <code>value</code> is of the type specified in the map, as result of executing this code with DownloadFiles(config):</p>
  
  <pre><code>        private static Dictionary&lt;string, object&gt; DownloadFiles(IConfigurationRoot config) {
              Dictionary&lt;string, object&gt; dataListByFileNames = new Dictionary&lt;string, object&gt;();
              listTypeByFileName.Keys.ToList()
                  .ForEach(name =&gt; dataListByFileNames.Add(name, DownloadData(name, config)));
              return dataListByFileNames;
          }
  
          private static object DownloadData(string name, IConfigurationRoot config) {
              _ = listTypeByFileName.TryGetValue(name, out Type listType);
              return new XmlSerializer(listType, new XmlRootAttribute("Document"))
                  .Deserialize(new StringReader(DownloadFromBlobStorage(name, config).ToString()));
          }
  
          private static CloudBlockBlob DownloadFromBlobStorage(string filetoDownload, IConfigurationRoot config) {
              return CloudStorageAccount.Parse(config["AzureWebJobsStorage"])
                  .CreateCloudBlobClient()
                  .GetContainerReference(config["BlobStorageContainerName"])
                  .GetBlockBlobReference(filetoDownload);
  </code></pre>
  
  <p>First question:  Is there a way I can make the return more typesafe?  Perhaps using parameterized types?</p>
  
  <p>The second part of the problem is actually consuming this <code>Dictionary</code>.</p>
  
  <p>For each type in this <code>Dictionary</code>, I now need a function like:</p>
  
  <pre><code>        private void AddA(Dictionary&lt;string, object&gt; dataByFileNames) {
              if (dataByFileNames.TryGetValue("a.xml", out object data)) {
                  List&lt;A&gt; aList = (List&lt;A&gt;)data;
                  aList.ForEach(a =&gt;
                      doSomethingWithA(a);
                  );
              }
          }
  
          private void AddB(Dictionary&lt;string, object&gt; dataByFileNames) {
              if (dataByFileNames.TryGetValue("b.xml", out object data)) {
                  List&lt;B&gt; bList = (List&lt;B&gt;)data;
                  bList.ForEach(b =&gt;
                      doSomethingWithB(b);
                  );
              }
          }
  
         // etc.
  </code></pre>
  
  <p>As I already have the list of filenames to types (top of this question), I feel there should be some way to abstract the above so it does not need to be repeated again and again and again.
  Note, it may be significant that every type (A, B, C, D, etc. all have a property <code>string Id</code> which will be definitely be needed for all <code>doStringWithX()</code> methods... if useful, I can create an interface to get this.  It is okay if I need to caste to the correct type within each <code>doStringWithX()</code> or when invoking each of these methods.c</p>