ManOfWar
ManOfWar

Reputation: 121

Simplify c# if/else statement with different List<>

Is there any way to simplify the following code? supportList is an object which is getting from constructor:

 public void FillCollection(object supportList)

Code here:

if (supportList is List<Bank>)
{
    foreach (var temp in supportList as List<Bank>)
    {
        //code here
    }
}
else if (supportList is List<Currency>)
{
    foreach (var temp in supportList as List<Currency>)
    {
        //code here
    }
}
else if (supportList is List<Amount>)
{
    foreach (var temp in supportList as List<Amount>)
    {
        //code here
    }
}

EDIT 1: All foreach parts do the same code like

foreach (var temp in supportList as List<Bank>)
{
    string yesno;
    if (temp.Id == CurrentId)
    {
        yesno = "" + yes;
    }
    else
    {
        yesno = "" + no;
    }

    CollectionSupport.Add(new SupportModel { Id = temp.Id, Name = temp.Name, 
    Code = temp.Code, YesNo = "" + yesno });
}

Upvotes: 0

Views: 813

Answers (2)

user743382
user743382

Reputation:

Make sure your classes implement a common interface.

public interface ISomeDescriptiveNameHere {
  public string Id { get; }
  public string Name { get; }
  public string Code { get; }
}

Then you can write

public void FillCollection(IReadOnlyList<ISomeDescriptiveNameHere> supportList) {
    foreach (var temp in supportList) {
       string yesno;
       if (temp.Id == CurrentId) {
           yesno = "" + yes;
       } else {
           yesno = "" + no;
       }
       CollectionSupport.Add(new SupportModel { Id = temp.Id, Name = temp.Name, Code = temp.Code, YesNo = "" + yesno });
   }
}

This relies on the fact that List<T> implements IReadOnlyList<T>, and IReadOnlyList<T> is covariant in T, meaning it can be transparently passed as IReadOnlyList<U> where U is any base class or implemented interface of T.

Upvotes: 2

Dai
Dai

Reputation: 155433

This looks like a duck-typing problem: where your Bank, Currency, and Amount types have the same members (Id, Name, and Code) but share no common hierarchy.

A solution is to create a new interface (I called it ICurrencyBankOrAmount) which declares these members, then add the interface to your Bank, Currency, and Amount model classes, then you can have a single loop body - I've converted it to a Linq expression for you below:

public void FillCollection<TItem>(List<TItem> supportList)
    where TITem : ICurrencyBankOrAmount
{

    this.CollectionSupport.AddRange(
        supportList
            .Select( item => new SupportModel()
            {
                Id = item.Id,
                Name = item.Name,
                Code = item.Code,
                YesNo = item.Id == this.CurrentId ? "yes" : "no"
            } )
    )
}

If you cannot modify those classes, you can use the Adapter Pattern.

Upvotes: 3

Related Questions