检查字符串列表是否包含任何枚举字符串值

时间:2014-06-18 17:51:23

标签: c# linq enums .net-3.5

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

假设我有一个字符串错误列表。 如何检查是否有“已知”错误?

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

这似乎不起作用。 如何在linq查询中访问StringValue而不必比较每个字符串?

修改

我使用Intersect尝试了@AK_解决方案,但是我收到了这个编译错误:

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.

真实场景是一个带有字符串字段的Error对象,其代码如下

class Error { string code; }

List<Error> errors = GetErrors();
var knownErrors = Enum.GetValues(typeof(KnownError));
bool exists = errors.Select(error => error.code).Intersect(knownErrors).Any();

2 个答案:

答案 0 :(得分:3)

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

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

Zack的评论是正确的:return errors.Intersect(knownErrors).Any更好...... +1他: - )

答案 1 :(得分:1)

Enum.IsDefined需要enum的对象包装实例。传递字符串名称不会产生所需的结果。

这应该有效:

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

请注意使用LINQ的Any代替将Count()与零进行比较:此方法效率更高,因为它会在找到第一个匹配项后立即停止。