Почему этот тест говорит мне, что значение равно нулю?

#c# #nunit

Вопрос:

У меня есть этот метод Zip:

 public static List<List<T>> Zip<T>(this List<List<T>> s)
    {
        if (s is null || s.Count == 0)
        {
            throw new ArgumentNullException(nameof(s));
        }
       foreach (var x in s)
           if (x == null)
               throw new ArgumentNullException();
        var count = s[0].Count;

        if (!s.All(x => x.Count == count))
            throw new ArgumentException("Not all sub lists have the same count.");

        var output = new List<List<T>>();

        for (int i = 0; i < count; i  ) //guardo la prima lista in s
        {
            var current_merged_list = new List<T>();

            foreach (var sub_list in s)  //per ogni lista in s
            {
                current_merged_list.Add(sub_list[i]);
            }

            output.Add(current_merged_list);
        }

        return output;
    }
 

Я написал этот тест:

 [TestCase(6)]
    public void Test3(int approx)
    {
        var abc = new List<string>() {"a", "b", "c"};
        var bca = new List<string>() { "b", "c", "a" };
        var cab = new List<string>() { "c", "a", "b" };
        var abcInf = AbcInf(abc);    //for some reason abcInf is null
        var bcaInf = BcaInf(bca);    //I guess this is null too
        var cabInf = CabInf(cab);    //I guess this is null too
        var dataList = new List<List<string>>();
        dataList.Add((abcInf as List<string>)); 
        dataList.Add((bcaInf as List<string>));
        dataList.Add((cabInf as List<string>));
        var actual = Check_Res_Approx(dataList.Zip(),approx);  
         var expected = ReturnResult(approx); 
         Assert.AreEqual(actual,expected);
    }
public IEnumerable<string> AbcInf(List<string> abc)
    {
        int i = 0;
        while (true)
        {
            var res = i;
            abc.Add("a");
            abc.Add("b");
            abc.Add("c");
            i  ;
            yield return abc[res];

        }
    }

    public IEnumerable<string> BcaInf(List<string> bca)
    {
        int i = 0;
        while (true)
        {
            var res = i;
            bca.Add("b");
            bca.Add("c");
            bca.Add("a");
            i  ;
            yield return bca[res];

        }
    }

    public IEnumerable<string> CabInf(List<string> cab)
    {
        int i = 0;
        while (true)
        {
            var res = i;
            cab.Add("c");
            cab.Add("a");
            cab.Add("b");
            i  ;

            yield return cab[res];

        }
    }

    public IEnumerable<IEnumerable<string>> Check_Res_Approx(List<List<string>> dataList, int approx)
    {
        int i = 0;
        while (i<approx)
        {
            yield return dataList[i];
        }
    }

    public IEnumerable<IEnumerable<string>> ReturnResult(int approx)
    {
        var abc = new List<string>()
        {
            "a",
            "b",
            "c"
        };
        var bca = new List<string>()
        {
            "b",
            "c",
            "a"
        };
        var cab = new List<string>()
        {
            "c",
            "a",
            "b"
        };
        var actual = new List<List<string>>();
        int i = 0;
        while (true)
        {
            actual.Add(abc);
            actual.Add(bca);
            actual.Add(cab);
            if (i < approx)
                yield return actual[i];
            yield break;
        }
    }
 

Я знаю, что это грязно, но мой вопрос не о самом тесте.
Мой вопрос в том, почему в нем говорится, что список abcInf равен нулю? Я заполнил его с помощью метода AbcInf(abc), поэтому я подумал ,что он должен содержать бесконечную последовательность [ a , b , c , a , b , c , a, b, c, …], но, по-видимому, это не так.

Комментарии:

1. «Я знаю, что это грязно, но мой вопрос не о самом тесте». — В таком случае, можете ли вы придумать более чистый и простой пример без всех ненужных деталей?

Ответ №1:

abcInf это не null так, и это не так List . Это ан IEnumerable<string> . Проблема в том , что вы пытаетесь преобразовать его в a List<string> , который является совершенно другим типом. Поскольку это преобразование невозможно, результатом abcInf as List<string> является null , как описано в документации по C#.

Если вы хотите построить a List<T> из an IEnumerable<T> , вам нужно вызвать конструктор, например: new List<string>(abcInf) . Однако, поскольку abcInf в этом случае он бесконечен, конструктор никогда не вернется.

Комментарии:

1. «вы должны вызвать конструктор» или ToList() из LINQ =)