Here is an implementation that uses as state a BigInteger instead of a bool[] or a BitArray:
using System.Numerics;
public static IEnumerable<(T[], T[])> GetCollectionPairs<T>(T[] source)
{
    BigInteger combinations = BigInteger.One << source.Length;
    for (BigInteger i = 0; i < combinations; i++)
    {
        yield return
        (
            Enumerable.Range(0, source.Length)
            .Where(j => (i & (BigInteger.One << j)) != 0)
            .Select(j => source[j])
            .ToArray(),
            Enumerable.Range(0, source.Length)
            .Where(j => (i & (BigInteger.One << j)) == 0)
            .Select(j => source[j])
            .ToArray()
        );
    }
}
Usage example:
var items = new string[] { "A", "B", "C", "D" };
var pairs = GetCollectionPairs(items);
foreach (var pair in pairs)
{
    Console.WriteLine(
        $"({String.Join("", pair.Item1)};{String.Join("", pair.Item2)})");
}
Output:
(;ABCD)
  (A;BCD)
  (B;ACD)
  (AB;CD)
  (C;ABD)
  (AC;BD)
  (BC;AD)
  (ABC;D)
  (D;ABC)
  (AD;BC)
  (BD;AC)
  (ABD;C)
  (CD;AB)
  (ACD;B)
  (BCD;A)
  (ABCD;)  
This generates (AB;CD) and (CD;AB) as different pairs. If this is not desirable, then simply loop until i < combinations / 2 instead of i < combinations.