将值从out修饰符返回到C#中的集合

时间:2019-06-24 07:56:54

标签: c# linq

假设我收到了用户的一些字符串。我需要将它们转换为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+个元素),并且在此处进行两次工作效率低下。

4 个答案:

答案 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...
}