Extending method chaining IEnumerable with Add..If I'm trying to write an extension (method chaining) for playing around a bit.
What I made work is an extension to add an item to the list (what is pretty easy):
IEnumerable&lt;int&gt; myList = originalList.Add(12);

What I now want to do is:
IEnumerable&lt;int&gt; myList = originalList.Add(12).If((list, @new) =&gt; !list.Contains(@new));

What it should do:
If the originalList doesn't already contain @new (12), then it may not add it to the list.
If the If-sequence is not added, the element gets added.
So this is my code:

public static class EnumerableExtension
{
    public static IAddEnumerable&lt;T&gt; Add&lt;T&gt;(this IEnumerable&lt;T&gt; @this, T element)
        =&gt; new AddEnumerable&lt;T&gt;(@this, element);
    
}

public interface IAddEnumerable&lt;T&gt; : IEnumerable&lt;T&gt;
{
    IEnumerable&lt;T&gt; If(Func&lt;IEnumerable&lt;T&gt;, T, bool&gt; expression);
}
            
internal class AddEnumerable&lt;T&gt; : IAddEnumerable&lt;T&gt;
{
    private IEnumerable&lt;T&gt; _sequence;
    private readonly T _elementToAdd;

    private bool _added;

    public AddEnumerable(IEnumerable&lt;T&gt; sequence, T elementToAdd)
    {
        _sequence = sequence;
        _elementToAdd = elementToAdd;
    }

    public IEnumerable&lt;T&gt; If(Func&lt;IEnumerable&lt;T&gt;, T, bool&gt; expression)
    {
        _added = true;

        if (expression(_sequence,_elementToAdd))
            _sequence = _sequence.AddItem(_elementToAdd);

        return this;
    }

    public IEnumerator&lt;T&gt; GetEnumerator()
    {
        if (_added) 
            return _sequence.GetEnumerator();

        _sequence = _sequence.AddItem(_elementToAdd);
        _added = true;

        return _sequence.GetEnumerator();
    }
            
    IEnumerator IEnumerable.GetEnumerator()
    {
        if (_added) 
            return _sequence.GetEnumerator();

        _sequence = _sequence.AddItem(_elementToAdd);
        _added = true;

        return _sequence.GetEnumerator();
    }
}

It works, but I wanted to ask, if there are any problems that could come up with, or if there is something I could do better.
I like the idea - but have the following comments:
  var originalList = Enumerable.Range(1, 12).ToList();
  IEnumerable&lt;int&gt; myList = originalList.Add(12).If((list, item) =&gt; !list.Contains(item));

If the originalList is defined explicit as something that implements ICollection, then you get a compiler error saying: &quot;Operator '.' cannot be applied to operand of type 'void'&quot;, because Add() is already a method returning void.


    public IEnumerator&lt;T&gt; GetEnumerator()
    {
        if (_added) 
            return _sequence.GetEnumerator();

        _sequence = _sequence.AddItem(_elementToAdd);
        _added = true;

        return _sequence.GetEnumerator();
    }
            
    IEnumerator IEnumerable.GetEnumerator()
    {
        if (_added) 
            return _sequence.GetEnumerator();

        _sequence = _sequence.AddItem(_elementToAdd);
        _added = true;

        return _sequence.GetEnumerator();
    }


Don't repeat code - the second method can call the first:
IEnumerator IEnumerable.GetEnumerator()
{
  return GetEnumerator();
}



public interface IAddEnumerable&lt;T&gt; : IEnumerable&lt;T&gt;
{
    IEnumerable&lt;T&gt; If(Func&lt;IEnumerable&lt;T&gt;, T, bool&gt; expression);
}


By renaming this interface you could extend its usability to for instance a sequence like:
data.Remove(12).If(&lt;predicate&gt;);

Maybe IPredicate or something like that.

Although I know that @new, @this etc. are valid variable names, I personally always avoid them, because they distract the reading. I have never been in a situation where it was unavoidable to use them.

I understand, that you want a fluid approach, and therefore define the If method separately, but I think, I would concatenate the behavior to a single function like:
public static IEnumerable&lt;T&gt; AddIf&lt;T&gt;(this IEnumerable&lt;T&gt; source, T element, Func&lt;IEnumerable&lt;T&gt;, T, bool&gt; predicate)
{
  return predicate(source, element) ? source.AddItem(element) : source;
}


An idea came to my mind: Because you return this from If(), I think, you can avoid the repetitive code in there by saving the predicate and then handle everything in GetEnumerator():
  internal class AddEnumerable&lt;T&gt; : IAddEnumerable&lt;T&gt;
  {
    private IEnumerable&lt;T&gt; _sequence;
    private readonly T _elementToAdd;
    private Func&lt;IEnumerable&lt;T&gt;, T, bool&gt; _expression;

    private bool _added;

    public AddEnumerable(IEnumerable&lt;T&gt; sequence, T elementToAdd)
    {
      _sequence = sequence;
      _elementToAdd = elementToAdd;
    }

    public IEnumerable&lt;T&gt; If(Func&lt;IEnumerable&lt;T&gt;, T, bool&gt; expression)
    {
      _expression = expression;
      return this;
    }

    public IEnumerator&lt;T&gt; GetEnumerator()
    {
      if (_added)
        return _sequence.GetEnumerator();

      if (_expression == null || _expression(_sequence, _elementToAdd))
      {
        _sequence = _sequence.AddItem(_elementToAdd);
      }
      _added = true;

      return _sequence.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
      return GetEnumerator();
    }
  }