Generic function, which populates a collection based on collection interface implementation As the above title states I have a function that I use to populate a collection's status names, currency names and other information that I do not store in the database.

This is my function:

    public static List&lt;T&gt; PopulateStatusNames&lt;T&gt;(List&lt;T&gt; items) where T : class
    {

        if (typeof(IStatusResult).IsAssignableFrom(typeof(T)))
        {
            Dictionary&lt;int, string&gt; statuses = new Dictionary&lt;int, string&gt;();

            if (typeof(IActivityStatusResult).IsAssignableFrom(typeof(T))) statuses = GlobalConstants.GetActivityStatuses();
            if (typeof(IPurchaseStatusResult).IsAssignableFrom(typeof(T))) statuses = GlobalConstants.GetPurchaseStatuses();
            if (typeof(IQuotationStatusResult).IsAssignableFrom(typeof(T))) statuses = GlobalConstants.GetQuotationStatuses();
            if (typeof(IInvoiceStatusResult).IsAssignableFrom(typeof(T))) statuses = GlobalConstants.GetInvoiceStatuses();

            foreach (var item in items.OfType&lt;IStatusResult&gt;())
            {
                item.StatusName = statuses[item.Status];
            }
        }

        if (typeof(ICurrencyResult).IsAssignableFrom(typeof(T)))
        {
            Dictionary&lt;int, string&gt; currencies = GlobalConstants.GetCurrencies();

            foreach (var item in items.OfType&lt;ICurrencyResult&gt;())
            {
                item.CurrencyName = currencies[item.Currency];
            }
        }

        return items;
    }


So if a collection implements an interface of type IStatusResult I look up the approapriate status names and loop through the collection to set the status name.

As you also notice in the above that I loop through my collection twice because if  my collection implements another type of interface I need to get a different set key value pairs so that I can look up the name

Is there a way to re-write the below function to populate status names, currency names in a single for loop

Sample POCO that implement these interfaces

Invoice:

public class InvoiceSearchResult : IInvoiceStatusResult, ICurrencyResult
{
    public int Id { get; set; }
    public string InvoiceNo { get; set; }
    public DateTime InvoiceDate { get; set; }
    public string Project { get; set; }
    public string Location { get; set; }
    public string Customer { get; set; }
    public int Currency { get; set; }
    public string CurrencyName { get; set; }
    public int Status { get; set; }
    public string StatusName { get; set; }
    public decimal Subtotal { get; set; }
    public decimal TotalTax { get; set; }
    public decimal Total { get; set; }
}


Location: 

public class LocationSearchResult : IActivityStatusResult
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Status { get; set; }
    public string StatusName { get; set; }
}


So as you can see I have a different combination of collections that implement these interfaces, based on the interfaces I am trying to figure out what needs to be populated
If you look closely there is actually four loops in your code. Two is explicit and other two from code like items.OfType&lt;IStatusResult&gt;() where if you look at the implementation of OfType&lt;T&gt; is looks something like below

foreach (object obj in source)
      {
        if (obj is TResult)
          yield return (TResult) obj;
      }


I would rather prefer to have one foreach loop to loop through all the items once and based on the type of each item, assign the appropriate properties something like below

foreach (var item in items)
            {
                if (typeof(ICurrencyResult).IsAssignableFrom(item.GetType()))
                {
                    item.CurrencyName = currencies[item.Currency];
                }
                else if (typeof(IStatusResult).IsAssignableFrom(item.GetType()))
                {
                    item.StatusName = statuses[item.Status];
                }
            }