I have the code below which implements a logic I need at two places in my code. The code is written in generic way.
It has a defect in it. It does not check whether the given object already exist in the collectionToBeExtended or not. It just add to it, and I will have twice the same item.
I use this code managing two collections, one contains Tags, the other one contains Link entities (POCO). They do not have the same parent object, nor interface. For managing the situation below I don't want to introduce a new common interface for them.
In order to fix the defect above I need put custom logic within the foreach to check whether the given object already member of the collection or not. The Tag and Entity object are different, so there is common ground for comparison. You can see the Tag implementation below.
DRY principle says clearly I should not create the exact implementations, instead I should create some generic solution can deal with both case, or a third and fourth one. My first thought was that, I introduce a switch where I can place custom logic based on object type, but Martin Fowler says in his Refactoring book that switch-cases are smelly areas.
My current knowledge and experience is not enough to solve this issue, so I really appreciate any help!
Generic implementation:
private ICollection<T> AddTo<T> ( IEnumerable<T> toBeAdded , ICollection<T> collectionToBeExtended )
{
if ( collectionToBeExtended == null )
{
collectionToBeExtended = new List<T> ( );
}
if ( toBeAdded != null )
{
foreach ( T obj in toBeAdded )
{
collectionToBeExtended.Add(obj);
}
}
return collectionToBeExtended;
}
Tag implementation:
private ICollection<Tag> AddTo ( IEnumerable<Tag> toBeAdded , ICollection<Tag> collectionToBeExtended )
{
if ( collectionToBeExtended == null )
{
collectionToBeExtended = new List<Tag> ( );
}
if ( toBeAdded != null )
{
foreach ( Tag tag in toBeAdded )
{
if (!collectionToBeExtended.Any(c => c.Id == tag.Id && c.Name == tag.Name))
{
collectionToBeExtended.Add(tag);
}
}
}
return collectionToBeExtended;
}