title: How to find the generic type of both Key/Value in IGrouping collection with c#?
body: <p>I have a ASP.NET MVC 5 based project that is written with c#. I've created a Razor helper that is called <code>@Html.DisplayTableFor(x =&gt; x.Records)</code> where <code>Records</code> implements <code>IEnumerable</code>.</p>
  
  <p>The <code>DisplayTableFor</code> extension method will create an HTML table where each <code>record</code> in the <code>Records</code> collection represents a row (<code>&lt;tr&gt;...&lt;/tr&gt;</code>) in the HTML table. It works great for me now when I just want to dump data into an HTML table. But, I like to expand it further so it can take grouped lists and render it also making a summary table look not just a raw data dump.</p>
  
  <p>If for example, I have the following row data</p>
  
  <pre><code>Name        Salary  Department
  John Doe    100000  IT
  Jane Doe    75000   Sales
  Jay T       50000   Sales
  Jack S      60000   Sales
  Mike S      65000   IT
  Dave B      70000   IT
  B Smith     80000   IT
  </code></pre>
  
  <p>Let's say I want to group the records by <code>Department</code> then by <code>Name</code>.I would want the <code>DisplayTableFor</code> method to generate something like this output in HTML table</p>
  
  <p><a href="https://i.stack.imgur.com/ECeiA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ECeiA.png" alt="enter image description here"></a></p>
  
  <p>Follow is my first approach to generate the summary-table. First I would inspect the generic type of the collection. If the generic type implements the <code>IGrouping</code> interface, then I would know that this collection is grouped and should be rendered as a summary table otherwise render the data as a data-dump format.</p>
  
  <p>This is the model that represents each raw row.</p>
  
  <pre><code>public class Record
  {
      public string Name { get; set; }
      public string Department { get; set; }
      public double Salary { get; set; }
  }
  
  public class RecordsKey
  {
      public string Name { get; set; }
      public string Department { get; set; }
  }
  </code></pre>
  
  <p>Here is how I would create my groped collection.</p>
  
  <pre><code>var records = new List&lt;Record&gt;(){.. some records ...}
  var grouped = records.GroupBy(x =&gt; new RecordsKey 
  {
   Department = x.Department,
   Name = x.Name
  }).ToList();
  </code></pre>
  
  <p>In my <code>DisplayTableFor</code> extension method, I execute the following code to find the <code>ModelMetadata</code> of the generic type (i.e. <code>IGouping&lt;RecordsKey, Records&gt;</code>)</p>
  
  <pre><code>Type type = TableHelpers.GetCollectionType(propertyMetadata.Model as IEnumerable);
  if (type == null)
  {
      throw new ArgumentException("Unable to find the generic type");
  }
  
  ModelMetadata typeMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, type);
  
  var columns = new Dictionary&lt;string, TableDataColumn&gt;();
  
  foreach (ModelMetadata propertyMetadata in propertyMetadatas)
  {
      // TODO... Execution steps
      // IF propertyMetadata.ModelType is assignable from IGrouping&lt;&gt;
      // 1) Find the generic type of the "IGrouping.Key" and foreach property on the Type create new TableDataColumn()
      // 2) Find the generic type of the "IGrouping.Value" and foreach property on the Type create a new TableDataColumn()
      // ELSE
      // columns.Add(new TableDataColumn(propertyMetadata));
      // ENDIF
  }
  </code></pre>
  
  <p>However, I am unable to convert TODO steps above comments into valid c# code.</p>
  
  <p>Question, how can I check if a type implements <code>IGrouping</code>? Also, how can I get the <code>ModelMetadata</code> of the <code>IGrouping.Key</code> and <code>IGrouping.Value</code>?</p>