Loop + Take for repeatedly taking elements from the same collection
Code optimization

This can be shortened:


while (true)
{
    if (TryMoveNext(enumerator, out enumerator))
    {
        moves++;

        if (startAt &gt; 0 &amp;&amp; moves &lt;= startAt)
        {
                continue;
        }

        yield return enumerator.Current;
    }
    else
    {
        yield break;
    }
}



To:

while (TryMoveNext(enumerator, out enumerator))
{
    moves++;

    if (startAt &gt; 0 &amp;&amp; moves &lt;= startAt)
    {
        continue;
    }

    yield return enumerator.Current;
}


You added the if for "boolean breaking", but at the same time you've subverted the inherent "boolean breaking" that a while loop provides.



Enumeration needed?

Since you are looking to repeat the same collection multiple times, this collection is cyclic in nature. Whenever I think about cyclic data, the modulo operator always comes to mind. It's by far the most common use case for the modulo operator.

According to this SO answer, though there may be a minor difference, the performance difference between enumeration and indexed arrays is reasonably negligible.
Keeping that in mind, I would advocate using a modulo operator simply because it keeps the code cleaner.

Note: The linked answer does not address re-enumeration, which is relevant for your code. But tbh, I'm not sure if re-enumeration is cached (thus not costing any meaningful overhead) or not. I'm going to continue my assumption that the performance differences are too small to be considered relevant for your current use case.

public static IEnumerable&lt;T&gt; Loop&lt;T&gt;(this IEnumerable&lt;T&gt; values, int startPosition = 0)
{
    if (values == null)
    {
        throw new ArgumentNullException(nameof(values));
    }

    T[] array = values.ToArray();
    int count = values.Count();

    while (true)
    {
        yield return array[startPosition++ % count];
    }
}


I kept the example terse (e.g. by inlining startPosition++), but I hope it highlights the reduced complexity of the code in general.

A slight improvement would be to not let startPosition grow beyond the array's size:

    while (true)
    {
        startPosition = (++startPosition) % count;
        yield return array[startPosition];
    }


Though I think this is only really useful if you expect to enumerate up to a point of integer overflow, which I doubt is the case here.



Footnote

I'm torn about the startPosition variable name. Once we start using it as a counter, its name is no longer correct (it's the current position). However, I do think it fits as a parameter name.
We can assign the value to a variable with a better name; but I'm not sure if it's really that necessary for such a terse piece of code.

I can see arguments for either case. I'm unable to make a conclusive decision on whether it's necessary. I'm open to feedback on this. 

If you do want to make the name more appropriate, I would suggest the following:

public static IEnumerable&lt;T&gt; Loop&lt;T&gt;(this IEnumerable&lt;T&gt; values, int? startPosition = null)
{
     //...

     int counter = startPosition ?? 0;

     //...
}