我有以下方法:
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;
});
}
它读取
xmlFileEntries
中的 xml 文件 frpm 路径,尝试反序列化它们,如果任何反序列化失败或反序列化集合xmlDtos
,则返回 null。如果我想扩展它的功能,并且不仅在反序列化失败时返回 null,而且还返回损坏的 xml 文件的路径(变量称为xml
),那么我的方法应该看起来像这样:
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);
});
}
但它不起作用,编译器强调
return (null, xml);
和 return (xmlDtos, null);
在 return
关键字上抛出 CS8030:
CS8030: Anonymous function converted to a void returning delegate cannot return a value.
CS8135 和 CS1662 在一个元组上:
CS8135: Tuple with 2 elements cannot be converted to type 'object'
但是如果我不返回 null 而不是字符串(将
return (xmlDtos, null);
替换为例如 return (xmlDtos, string.Empty);
),编译器将停止给出错误。我究竟做错了什么?可能是我不明白 lambda 是如何正确工作的?
Task.Run
可以采用几种不同类型的委托参数,编译器很难确定您要传递给它的类型。您可以通过执行以下一项或多项操作来帮助它:
null
:return (xmlDtos, (string?) null);
Task.Run<(List<T>?, string?)>(...)
为什么将非异步功能包装在任务中?只要使这个方法异步,那么你就不需要 Task.Run。
public Task<(List<T>?, string?)> ReadXmlAsync<T>(IEnumerable<string> xmlFileEntries)
{
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 Task.FromResult((default(List<T>), xml));
xmlDtos.Add(dto);
}
return Task.FromResult((xmlDtos, default(string)));