Strange compiler error with return types inside lambda inside task run

I have the following method:

    public Task<List<T>?> ReadXmlAsync<T>(IEnumerable<string> xmlFileEntries)
    {
        return Task.Run(() =>
        {
            var xmlDtos = new List<T>();
            var serializer = new XmlSerializer(typeof(T));

            foreach (var xml in xmlFileEntries)
            {
                using var fs = new FileStream(xml, FileMode.Open);

                if (serializer.Deserialize(fs) is not T dto)
                    return null;

                xmlDtos.Add(dto);
            }

            return xmlDtos;
        });
    }

It reads xml files frpm paths in xmlFileEntries, tries to deserialize them and returns either null if any deserialization fails or deserialized collection xmlDtos. If I want to expand its functionality and return not only null if deserialization fails but also path to the damaged xml file (variable called xml), so my method should look something like that:

    public Task<(List<T>?, string?)> ReadXmlAsync<T>(IEnumerable<string> xmlFileEntries)
    {
        return Task.Run(() =>
        {
            var xmlDtos = new List<T>();
            var serializer = new XmlSerializer(typeof(T));

            foreach (var xml in xmlFileEntries)
            {
                using var fs = new FileStream(xml, FileMode.Open);

                if (serializer.Deserialize(fs) is not T dto)
                    return (null, xml);

                xmlDtos.Add(dto);
            }

            return (xmlDtos, null);
        });
    }

But it does not work, compiler underscores return (null, xml); and return (xmlDtos, null); throwing CS8030 on return keyword:

CS8030: Anonymous function converted to a void returning delegate cannot return a value.

CS8135 and CS1662 on a tuple:

CS8135: Tuple with 2 elements cannot be converted to type 'object'

But if I don’t return null instead of string (replace return (xmlDtos, null); with, for example return (xmlDtos, string.Empty);) compiler stops giving errors. What am I doing wrong? May it be that I don’t understand how lambda works correctly?

>Solution :

Task.Run can take several different types of delegate parameters, and the compiler is having a hard time figuring out which type you’re passing in to it. You can help it by doing one or more of the following:

  • Cast the null in the return type: return (xmlDtos, (string?) null);
  • Provide an explicit generic type to Task.Run: Task.Run<(List<T>?, string?)>(...)

Leave a Reply