2017-10-13 104 views
0

我想将此方法中的foreach转换为linq表达式。我有2个try/catches,因为我不能总是指望在guid列表中传递的字符串,或者guidToFind是有效的guid字符串。foreach linq与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; 
    } 
+0

你们快速的回应。而且,对不起,我修改了原来的方法以包含第二次try/catch ......这是因为如果列表中的某个字符串不好,意味着它不能被转换为guid, t立即退出并报错。它应该尝试列表中的所有项目。 – Kershaw

+0

是空的Guid可以在字符串的Guid列表中? –

回答

5
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; 
} 
+0

这正是我需要它做的。如果guidToFind在列表中,它返回true,否则返回false,并且使用GuidTryParse处理列表中任何错误的guid字符串。一个改进就是取消该块中的try/catch,并在guidToFind上执行TryParse。我会尽力做到这一点。 – Kershaw

+0

@Kershaw我同意这是一个更好的方法,并考虑在我的答案中包括,但它似乎超出了问题的范围,所以我只实现了LINQ。 –

6
var tg = Guid.Empty; 
    guids.Any(g=> g!= null 
     && Guid.TryParse(g.Trim(), out tg) && new Guid(g.Trim()) == guid) 
+0

这很好很紧密,并且工作很好,除非列表中的一个guid字符串无效。如果你知道guid字符串和guidToFind字符串都是有效的,那么我会推荐这个作为有效答案。 – Kershaw

+1

@Kershaw,你应该使用'TryParse'而不是捕捉和吞咽异常这是丑陋的 –

+1

你应该使用'TryParse'来进行第一次转换 –

-1

不是简洁的其他解决办法,但我觉得它可读

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

THX为伟大的答案,但我与Jason Boyds答案去,但有对我自己的轻微修改以摆脱最后的尝试/捕获。我已经运行这些测试的结果我的预期:

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

UPDATE: 从上述方法的代码审查反馈后,我能够让更多的refinemen TS,这是结果:

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

这个答案是不是已经发布的其他特别的不同,但我会亲自使用:

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#特性例如“出变种的结果”(个人喜好)
  • 明确参数验证(取决于你在以后的行为,但我是一个大风扇)

最后一个项目我引到一个普遍的观点: 如果你的程序将输入的字符串集合作为GUID,为什么不在当时验证这些字符串并保持IEnumerable Guid?做同样的事情的GUID找到和代码变成:

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

我喜欢你所做的抛出相关的异常,这可能会有用如果它是理想的。但在这种特殊情况下,我不在乎知道哪里出了问题,我只想知道guidToFind是否在列表中,并且如果在guidToFind中传递无效,则返回false。在正确的背景下,这当然是一个有效的答案。 – Kershaw