Purrx
Purrx

Reputation: 63

Switch Collection In a Foreach

Both of the collections have ExternalIds. How would I change the collection the foreach uses depending if the argument type is 1 or 2. Do I have to do two separate loops or can I somehow use a collection T ?

        public ActionResult Details(string id, int type)
        {
           IEnumerable<Album> collection1 = ASR.Albums;
           IEnumerable<Track> collection2 = TSR.Tracks;


           foreach (var item in collection1)
           {
               var result = item.ExternalIds.SingleOrDefault(x => x.Id == id);
               if (result != null)
               {
                   return View(item);
               }
           }
           return View();
        }

Upvotes: 1

Views: 110

Answers (3)

Michel Keijzers
Michel Keijzers

Reputation: 15367

Make an interface with ExternalIds as member, let Album and Track derive from that interface.

    public interface IExternalIds
    {
        public IEnumerable<SomeType> ExternalIds { get; }
    }

    public class Album: IExternalIds
    {
        ...
    }

    public class Track: IExternalIds
    {
        ...
    }

    public ActionResult Details(string id, int type)
    {
       IEnumerable<Album> collection1 = ASR.Albums;
       IEnumerable<Track> collection2 = TSR.Tracks;
       var collectionToUse = ((type == 1) ? collection1 : collection2)
        as IEnumerable<IExternalIds>;

       foreach (var item in collectionToUse)
       {
           var result = item.ExternalIds.SingleOrDefault(x => x.Id == id);
           if (result != null)
           {
               return View(item);
           }
       }
       return View();
    }

Upvotes: 2

Niels Filter
Niels Filter

Reputation: 4528

Do album and track have a common base type? If so, you can do something like this:

IEnumerable<BaseType> collection = type == 1 ? ASR.Albums : TSR.Tracks;
foreach (var item in collection)
{
   ...
}

If you don't have a common base type, create an interface, add the common properties you'll need in the foreach, apply it to Album and Track and then do something like this:

IEnumerable<IMusicInfo> collection = type == 1 ? ASR.Albums : TSR.Tracks;
foreach (var item in collection)
{
   ...
}

Remember to name your interface well and add only properties that make sense within that interface for good coding practices

Upvotes: 0

Andrei Olaru
Andrei Olaru

Reputation: 304

I think that you wanted them to have a base class/interface. Let me exemplify this for you:

public interface IEntity
{
    public List<YourListType> ExternalIds { get; set; }
}

Then you implement the IEntity interface in both your classes:

public class Album : IEntity
{
    public List<YourListType> ExternalIds { get; set; }
}

After this is done, you can have your code looking like this:

    public ActionResult Details(string id, int type)
    {
       IEnumerable<IEntity> collection1 = ASR.Albums;
       IEnumerable<IEntity> collection2 = TSR.Tracks;
       var collectionToUse = (type == 1) ? collection1 : collection2;

       foreach (var item in collectionToUse)
       {
           var result = item.ExternalIds.SingleOrDefault(x => x.Id == id);
           if (result != null)
           {
               return View(item);
           }
       }
       return View();
    }

So, by implementing an interface that you will implement in both your classes, you can use the common properties that are declared into the interface.

I hope this answers your question.

Upvotes: 0

Related Questions