2
enum KnownError
{
    [StringValue("CODE-001")]
    CODE001,
    [StringValue("CODE-002")]
    CODE002,
    [StringValue("CODE-003")]
    CODE003,
    [StringValue("CODE-004")]
    CODE004,
    [StringValue("CODE-005")]
    CODE005
}

List<string> errors = {"ahah", "eheh", "CODE-005", "uhuh"};

Let's say i have a list of string errors. How can I check if any error is "known"?

bool ContainsKnownError(List<string> error)
{
    return errors.Where(error => Enum.IsDefined(typeof(KnownError), error) == true).Count() > 0;
}

This doesn't seem to work. How can I access StringValue inside the linq query without having to compare each string?

EDIT

I tried @AK_ solution, using Intersect, but I'm getting this compilation error:

The type arguments for method 'System.Linq.Enumerable.Intersect<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Collections.Generic.IEnumerable<TSource>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

The real scenario is an Error object with a string field with the code like this

class Error { string code; }

List<Error> errors = GetErrors();
var knownErrors = Enum.GetValues(typeof(KnownError));
bool exists = errors.Select(error => error.code).Intersect(knownErrors).Any();
Hélder Gonçalves
  • 3,822
  • 13
  • 38
  • 63
  • So your issue is that the error code is not exactly same as `enum`, but instead its string value, right ? – Habib Jun 18 '14 at 17:58
  • 1
    I think you'll find your answer either at http://stackoverflow.com/q/424366/56778, or possibly http://www.codeproject.com/Articles/11130/String-Enumerations-in-C. You should mention in your question that `StringValue` is a custom attribute, *not* something that's supplied by .NET. – Jim Mischel Jun 18 '14 at 18:28
  • @Habib Yes, I just created an enum to make it easier to handle the errors. – Hélder Gonçalves Jun 18 '14 at 19:14

2 Answers2

3
var knownErrors = Enum.GetValues(typeof(KnownError));

return errors.Contains(error => knownErrors.Contains(error));
//or cooler:
return errors.Intersect(knownErrors).Count() > 0;

Zack's comment is correct:return errors.Intersect(knownErrors).Any is better... +1 him :-)

AK_
  • 7,981
  • 7
  • 46
  • 78
  • 2
    I'd change `return errors.Intersect(knownErrors).Count() > 0;` to `return errors.Intersect(knownErrors).Any();` because `Any()` will terminate at the first match, rather than after processing every element of both sets (which `Count()` will do). – Zack Butcher Jun 18 '14 at 18:15
1

Enum.IsDefined expects an object-wrapped instance of the enum. Passing a string name does not produce the desired result.

This should work:

KnownError ignore;
var res = errors.Any(errorCode => Enum.TryParse<KnownError>(errorCode, out ignore));

Note the use of LINQ's Any in place of comparing Count() to zero: this approach is more efficient, because it stops as soon as it finds the first match.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523