简体   繁体   中英

foreach to linq with guid comparison

I would like to convert the foreach in this method to a linq expression. I have 2 try/catches because I can't always count on the strings that are passed in the list of guids or guidToFind to be valid guid strings.

    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;
    }
   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)
{
    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;
}

This answer is not particularly different to the others already posted, but I would personally use this:

    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);
    }

The differences being:

  • extension method (personal preference)
  • newer C# features eg 'out var result' (personal preference)
  • explicitly validating parameters (depends on the behaviour you are after, but I'm a big fan)

The last item leads me to a general point: If your program is taking as input a collection of strings that are meant to be GUIDs, why not validate those at the time and keep an IEnumerable of Guid? Do the same thing for the GUID to find and the code becomes:

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

Thx for the great answers, however I went with Jason Boyds answer, but with a slight modification of my own to get rid of the last try/catch. I have run these tests with the results I expected:

  • bad guidToFind string
  • good guidToFind string, list of all valid guid strings
  • good guidToFind string, list of mostly valid guid strings

     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); } 

UPDATE: After feedback from a code review with the above method, I was able to make more refinements and this is the result:

    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;
        });
    }

not as terse as the other solution, but I find it readable

    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);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM