USS-Montana
USS-Montana

Reputation: 417

Convert a for loop nested in a ForEach loop to LINQ

I'm getting a compilation error "not all code paths return a value" on the following code, How come?!

 public class SomeEntity
    {
        public int m_i;
        public SomeEntity(int i)
        {
            m_i = i;
        }

        public override string ToString()
        {
            return m_i.ToString();
        }


        public static int someFunction(int i) { return i + 100; }

        public static IEnumerable GetEntities()
        {
            int [] arr = {1,2,3};
            foreach (int i in arr)
            {

                //        for (int i = 0; i < someArray.Count();i++)
                //            yield return new SomeEntity(someFunction(i));

                // *** Equivalent linq function ***    
                return Enumerable.Range(0, 7).Select(a => new SomeEntity(someFunction(a)));
            }
        }
    }

I can't seem to figure this out..... I tried converting the outer foreach loop to a linq expression

public static IEnumerable GetEntities()
        {
            int [] arr = {1,2,3};

            return arr.Select(Xenv =>
                 Enumerable.Range(0, 7).Select(a => new SomeEntity(someFunction(a)))
                );
        }

but then I just got an error :/

Upvotes: 3

Views: 268

Answers (4)

Hamawi
Hamawi

Reputation: 235

The yield code you are replacing returned IEnumrable<SomeEntity> while the new code returns IEnumarable<IEnumrable<SomeEntity>>.

you can use SelectMany

public static IEnumerable GetEntities()
        {
            int [] arr = {1,2,3};

            return arr.SelectMany(Xenv =>
                 Enumerable.Range(0, 7).Select(a => new SomeEntity(someFunction(a)))
                );
        }

on side note, you use the old non-generic IEnumerable which prevent .Net compiler from doing type consistency checks. always use the generic one IEnumerable<> with the specific type.

Upvotes: 1

Shakir Ahamed
Shakir Ahamed

Reputation: 1308

If you are using any return type on your method you have to return anything with type of method in before the final braces of method like below.you no need to return anything if your using return type as void

public static IEnumerable GetEntities()
{
     int [] arr = {1,2,3};
     foreach (int i in arr)
     {

            //        for (int i = 0; i < someArray.Count();i++)
            //            yield return new SomeEntity(someFunction(i));

            // *** Equivalent linq function ***    
            var numcol = Enumerable.Range(0, 7).Select(a => new SomeEntity(someFunction(a)));
     }

    return numcol;
}

Upvotes: 0

jthomperoo
jthomperoo

Reputation: 93

The problem is with the 'foreach' loop: the program cannot assume that the loop will always iterate it through it at least once.

If the array being iterated through was a length 0 the code within the loop would not be called; and therefore the return statement would not be triggered; resulting in the error that not all code paths return a value. In order to fix this you need to put a return statement outside of the loop:

public static IEnumerable GetEntities()
    {
        int [] arr = {1,2,3};
        foreach (int i in arr)
        {

            //        for (int i = 0; i < someArray.Count();i++)
            //            yield return new SomeEntity(someFunction(i));

            // *** Equivalent linq function ***    
            return Enumerable.Range(0, 7).Select(a => new SomeEntity(someFunction(a)));
        }
        //INSERT RETURN STATEMENT HERE
    }

Upvotes: 1

Phillip Ngan
Phillip Ngan

Reputation: 16086

Because it is possible that arr is empty and you'll not return inside the foreach loop. Put a return after the foreach loop.

public static IEnumerable GetEntities()
{
    int[] arr = { 1, 2, 3 };
    foreach (int i in arr)
    {

        //        for (int i = 0; i < someArray.Count();i++)
        //            yield return new SomeEntity(someFunction(i));

        // *** Equivalent linq function ***    
        return Enumerable.Range(0, 7).Select(a => new SomeEntity(someFunction(a)));
    }
    return Enumerable.Empty<int>(); // <<<< this is what you need
}

Upvotes: 6

Related Questions