Search code examples
c#aws-lambda

Cannot Return A Value From Iterator C#


I am attempting to return an Enumerable value with an asynchronous function.

I'm having a problem converting the returned data type value to the "main" method, because there is an asynchronous call made within it. I keep implementing the changes recommended and what I read online, but everytime I make a change Visual Studio doesn't like something else I've done, and then I have to go back.

The error is on the "ListOfLambdas" function. Specifically, it is on the "yield return" line. The Error number is [CS0029][1]

What are you looking to do? I'm looking to capture a list/iterable value that I can then pass around and do other work on.

public void FunctionHandler()
{


    IAsyncEnumerable<AWSLambda> returnedListOfLambdas = ListOfLambdas();
}

private async IAsyncEnumerable<AWSLambda> ListOfLambdas()
{
    //Instantiating Client:
    var lambdaClient = new AmazonLambdaClient();
    //Instantiating New Lambda List:
    List<AWSLambda> list = null;
    //Getting List
    var response = await lambdaClient.ListFunctionsAsync();
    response.Functions.ForEach(function =>
    {
        AWSLambda aWSLambda = MapLambda(function);
        if(list == null)
        {
            list = new List<AWSLambda>();
        }
        list.Add(aWSLambda);
    });
    yield return list; //Here is our error.
}



private static AWSLambda MapLambda(FunctionConfiguration function)
{
    AWSLambda lambdaToBeAdded = new AWSLambda();
    lambdaToBeAdded.FunctionName = function.FunctionName.ToString();
    lambdaToBeAdded.FunctionARN = function.FunctionArn.ToString();
    lambdaToBeAdded.FunctionDescription = function.FunctionName.ToString();
    lambdaToBeAdded.FunctionRunTime = function.Runtime.ToString();
    lambdaToBeAdded.FunctionMemorySize = function.MemorySize.ToString();
    lambdaToBeAdded.FunctionTimeout = function.Timeout.ToString();
    lambdaToBeAdded.FunctionHandler = function.Handler.ToString();
    return lambdaToBeAdded;
}

The error that I am getting is specifically, "Cannot implicitly convert type 'System.Collections.Generic.List<saveFileS3.AWSLambda> to 'saveFileS3.AWSLambda'

But this seems strange to me. I think it is rather clear that the 'list' variable is not that data type. What am I missing? [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0029?f1url=%3FappId%3Droslyn%26k%3Dk(CS0029)


Solution

  • List<AWSLambda> list = null; is exactly System.Collections.Generic.List<saveFileS3.AWSLambda>, hence why the compiler is complaining when you're trying to return AWSLambda.

    You need a foreach with a nested yield return:

    foreach (var lambda in list)
        yield return lambda;
    

    Ideally, you'd rewrite as such:

    private async IAsyncEnumerable<AWSLambda> ListOfLambdas()
    {
        using (var lambdaClient = new AmazonLambdaClient())
        {
            var response = await lambdaClient.ListFunctionsAsync();
            foreach (var function in response.Functions)
            {
                yield return MapLambda(function);
            }
        }
    }
    

    Note that AmazonLambdaClient implements IDisposable so it should be disposed when you're finished with it.