foreach 到 linq 与 guid 比较

foreach to linq with guid comparison

我想将此方法中的 foreach 转换为 linq 表达式。我有 2 try/catches,因为我不能总是指望在 guid 或 guidToFind 列表中传递的字符串是有效的 guid 字符串。

    public static bool IsGuidInList(List<string> guids, string guidToFind)
    {
        try
        {
            var guid = new Guid(guidToFind.Trim());
            foreach (var g in guids)
            {
                try
                {
                    var g2 = new Guid(g.Trim());
                    if (g2 == guid)
                        return true;
                }
                catch {} // swallow exception
            }
        }
        catch{} // swallow exception
        return false;
    }
public static bool IsGuidInList(List<string> guids, string guidToFind)
{
    try
    {
        var guid = new Guid(guidToFind.Trim());
        return
            guids
            .Select(x =>
            {
                Guid result;
                return Guid.TryParse(x, out result) ? (Guid?)result : null;
            })
            .Where(x => x.HasValue)
            .Any(x => x.Value == guid);
    }
    catch { } // swallow exception
    return false;
}
   var tg = Guid.Empty; 
   guids.Any(g=> g!= null 
       && Guid.TryParse(g.Trim(), out tg) && new Guid(g.Trim()) == guid)

不像其他解决方案那么简洁,但我觉得它可读

    public static bool IsGuidInList(List<string> guids, string guidToFind)
    {
        Guid outGuid;

        var inGuidToFind = Guid.TryParse(guidToFind, out outGuid) ? outGuid : Guid.Empty;
        if (inGuidToFind == Guid.Empty)
            return false;

        var inGuids = new List<Guid>();
        guids.Where(i => Guid.TryParse(i, out outGuid)).ForEach(i => inGuids.Add(new Guid(i)));

        return inGuids.Contains(inGuidToFind);
    }

感谢伟大的答案,但是我选择了 Jason Boyds 的答案,但我自己做了一些小修改以摆脱最后一个 try/catch。我有 运行 这些测试,结果是我预期的:

  • 错误的 guidToFind 字符串
  • 好的 guidToFind 字符串,所有有效 guid 字符串的列表
  • 好的 guidToFind 字符串,最有效的 guid 字符串列表

    public static bool IsGuidInList(List<string> guids, string guidToFind)
    {
        Guid guid;
        if (!Guid.TryParse(guidToFind.Trim(), out guid))
            return false;
    
        return
            guids
                .Select(x =>
                {
                    Guid result;
                    return Guid.TryParse(x, out result) ? (Guid?)result : null;
                })
                .Where(x => x.HasValue)
                .Any(x => x.Value == guid);
    }
    

更新: 在使用上述方法进行代码审查后得到反馈,我能够进行更多改进,结果如下:

    public static bool IsGuidInList(IEnumerable<string> guids, string guidToFind)
    {
        Guid guid;
        if (!Guid.TryParse(guidToFind.Trim(), out guid))
            return false;

        return guids.Any(x => { Guid result;
            Guid.TryParse(x, out result);
            return result == guid;
        });
    }

这个答案与其他已经发布的答案没有特别不同,但我个人会使用这个:

    public static bool ContainsGuid(this IEnumerable<string> guids, string guidToFind)
    {
        if (guids == null) throw new ArgumentNullException(nameof(guids));
        if (guidToFind == null) throw new ArgumentNullException(nameof(guidToFind));

        if (!Guid.TryParse(guidToFind, out var guid)) 
            throw new ArgumentException($"Could not convert '{guidToFind}' to a GUID");

        return guids
            .Select(s => Guid.TryParse(s, out var result) ? (Guid?)result : null)
            .Contains(guid);
    }

不同之处在于:

  • 扩展方式(个人喜好)
  • 更新的 C# 功能,例如'out var result'(个人喜好)
  • 显式验证参数(取决于您所追求的行为,但我是忠实拥护者)

最后一项使我得出一个一般性观点: 如果您的程序将作为 GUID 的字符串集合作为输入,为什么不在当时验证这些字符串并保留 Guid 的 IEnumerable?为找到 GUID 做同样的事情,代码变为:

IEnumerable<Guid> guidList = // validated elsewhere
var found = guidList.Contains(guid);