假设我收到了用户的一些字符串。我需要将它们转换为GUID序列以进行进一步处理。用户可能会输入无效的数据(不正确的GUID序列),因此我需要验证输入。另外,如果只有所有上载的数据都是正确的GUID值,我可以运行业务流程。这是我的代码:
IEnumerable<string> userUploadedValues = /* some logic */;
bool canParseUserInputToGuid = userUploadedValues.All(p => Guid.TryParse(p, out var x));
if(canParseUserInputToGuid)
var parsedUserInput = userUploadedValues.Select(p=> Guid.Parse(p));
这种逻辑效果很好,但是我不喜欢它,因为我实际上在做两次工作。在第二行中,Guid.TryParse(p, out var x)
已将已解析的GUID序列写入X变量。是否有一种组合验证和映射逻辑的方法-如果序列元素满足条件(All
),然后在一个查询中将此元素映射到新集合(Select
)?在性能方面对我来说也很重要,因为客户端可能会发送大量数据(1,000,000+个元素),并且在此处进行两次工作效率低下。
答案 0 :(得分:3)
您可以在一个Select
中执行以下操作:
var parsedUserInput = userUploadedValues.Select(p => Guid.TryParse(p, out var x) ? x : default)
.Where(p => p != default);
为此,您需要确定是否没有来自用户的Guid.Empty
输入。
否则,如果解析不成功,则可以返回可为空的Guid
:
var parsedUserInput = userUploadedValues.Select(p => Guid.TryParse(p, out var x) ? x : default(Guid?))
.Where(p => p != null);
通过创建扩展方法的另一种解决方案,例如:
public static class MyExtensions
{
public static Guid? ToGuid(this string arg)
{
Guid? result = null;
if(Guid.TryParse(arg, out Guid guid))
result = guid;
return result;
}
}
和用法:
var parsedUserInput2 = userUploadedValues.Select(p => p.ToGuid())
.Where(p => p != null);
但是请记住,在这种情况下,您将有一组可为空的Guid。
答案 1 :(得分:1)
在无效的out var x
情况下,您的Guid.Empty
变量将为Guid
。因此,您可以执行以下操作:
IEnumerable<string> userUploadedValues = new[]
{
"guids.."
};
var maybeGuids = userUploadedValues.Select( x => {
Guid.TryParse( x, out var @guid );
return @guid;
} );
if ( maybeGuids.All( x => x != Guid.Empty ) )
{
//all the maybe guids are guids
}
答案 2 :(得分:1)
您可以像下面那样优化验证和转换,
IEnumerable<string> userUploadedValues = /* some logic */;
var parsedGuids = userUploadedValues.Where(p => Guid.TryParse(p, out var x));
if(userUploadedValues.Count() != parsedGuids.Count())
{
//Some conversion failed,
}
如果两个列表的计数相同,则您在parsedGuid中具有所有已转换的GUID。
答案 3 :(得分:1)
有时,非LINQ方法更易于阅读,而且不再使用。
var parsedUserInput = new List<string>();
foreach(var value in userUploadedValues)
{
if (Guid.TryParse(value, out var x)) parsedUserInput.Add(x);
else...
}