How to manage this situation using general programming in C #?

I have the code below that implements the logic I need in two places in my code. The code is written in a general way.

There is a defect in it. It does not check if a given object exists in the ToBeExtended collection or not. He just adds to it, and I will have the same element twice.

I use this code to manage two collections, one contains tags, the other contains Link objects (POCO). They do not have the same parent and interface. To manage the situation below, I do not want to introduce a new common interface for them.

To fix the defect above, I need to put the user logic inside the foreach to check if this object is already a member of the collection or not. The Tag and Entity objects are different, so there is a common basis for comparison. You can see the implementation of the tag below.

The DRY principle says that I should not create exact implementations, instead I should create some kind of general solution that can deal with both the register and the third and fourth. My first thought was that I imagine a switch where I can place user logic based on an object type, but Martin Fowler says in his book Refactoring that wiring closets are smelly areas.

My current knowledge and experience is not enough to solve this problem, so I really appreciate any help!

General 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;
    }

:

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;
    }
+4
4

# x.Equals(y). , .

IEnumerable<A> . ICollection<A> , IEnumerable<A>.

collectionToBeExtended.Concat(toBeAdded).Distinct()
+3

, , , , . , .

public static ICollection<X> AddIf<X>(this ICollection<X> myarray, X val, Func<X, X, bool> check)
    {
        if (myarray.All<X>((c) => check(c, val))) myarray.Add(val);
        return myarray;
    }

List<string> test = new List<string> { "1", "2", "3", "4", "5" };
test.AddIf<string>("1", (a, b) => !a.Equals(b)); //this will not be added
test.AddIf<string>("6", (a, b) => !a.Equals(b)); //this will be added

collectionToBeExtended.AddIf((c, tag) => !c.Id.Equals(tag.Id) && !c.Name.Equals(tag.Name))

.

+2

IEquatable<T> Tag

public class Tag : IEquatable<Tag>
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Equals(Tag other)
    {
        return Id == other.Id && Name == other.Name;
    }

    ...
}

private ICollection<T> AddTo ( IEnumerable<T> toBeAdded , ICollection<T> collectionToBeExtended )
{

    if ( collectionToBeExtended == null )
    {
        collectionToBeExtended = new List<T> ( );
    }

    if ( toBeAdded != null )
    {
        foreach ( T t in toBeAdded )
        {
            if (!collectionToBeExtended.Contains(t))
            {
                collectionToBeExtended.Add(t);
            }
        }
    }

    return collectionToBeExtended;
}

IEquatable<T> , AddTo. . . IEquatable?.

. ,

private ICollection<T> AddTo<T>(IEnumerable<T> toBeAdded, ICollection<T> collectionToBeExtended, Func<T, T, bool> comparer)
{

    if (collectionToBeExtended == null)
    {
        collectionToBeExtended = new List<T>();
    }

    if (toBeAdded != null)
    {
        foreach (T t in toBeAdded)
        {
            if (!collectionToBeExtended.Any(existingT => comparer(t, existingT))))
            {
                collectionToBeExtended.Add(t);
            }
        }
    }

    return collectionToBeExtended;
}

AddTo(tags, collection, (t1, t2) => t1.Id == t2.Id && t1.Name == t2.Name);. - , .

+2

IEquatable<T> Tag , , where T:IEquatable<T> , .

, HashSet<T>, HashSet<T> Constructor (IEqualityComparer<T>)?

+1

All Articles