I like the idea - but have the following comments:
var originalList = Enumerable.Range(1, 12).ToList();
IEnumerable<int> myList = originalList.Add(12).If((list, item) => !list.Contains(item));
If the originalList
is defined explicit as something that implements ICollection
, then you get a compiler error saying: "Operator '.' cannot be applied to operand of type 'void'
", because Add()
is already a method returning void
.
public IEnumerator<T> 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<T> : IEnumerable<T>
{
IEnumerable<T> If(Func<IEnumerable<T>, T, bool> expression);
}
By renaming this interface you could extend its usability to for instance a sequence like:
data.Remove(12).If(<predicate>);
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<T> AddIf<T>(this IEnumerable<T> source, T element, Func<IEnumerable<T>, T, bool> predicate)
{
return predicate(source, element) ? source.AddItem(element) : source;
}