使用Find()根据枚举值查找集合中的实例

Oys*_*ein 0 c# enums

我正在尝试根据对象中的Enum类型属性在集合中查找对象.但它总是返回NULL,即使我验证集合确实包含具有预期属性值的对象.为什么是这样?

public enum FooEnum
{
    First, Second, Third, Fourth
}

public class Foo
{
    public Enum EnumValue { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var fooCollection = new List<Foo>();
        fooCollection.Add(new Foo() { EnumValue = FooEnum.First });
        fooCollection.Add(new Foo() { EnumValue = FooEnum.Second });
        fooCollection.Add(new Foo() { EnumValue = FooEnum.Third });

        var fooSearchInstance = new Foo() { EnumValue = FooEnum.Fourth };

        var fooFoundInstance = fooCollection.Find(f => f.EnumValue == fooSearchInstance.EnumValue);  // NULL, for obvious reasons

        fooSearchInstance.EnumValue = FooEnum.Second;
        fooFoundInstance = fooCollection.Find(f => f.EnumValue == fooSearchInstance.EnumValue);  // Also NULL - Why??

    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

这个框FooEnum.Second,并将结果引用存储在fooSearchInstance.Enum:

fooSearchInstance.Enum = FooEnum.Second;
Run Code Online (Sandbox Code Playgroud)

此框FooEnum.Second和使用参考标识将其与f.Enum以下内容进行比较:

f.Enum == fooSearchInstance.Enum
Run Code Online (Sandbox Code Playgroud)

你有两次拳击,所以你创建了单独的对象 - 引用标识对你不起作用.你得到的代码是一个更复杂的形式:

Enum x = FooEnum.Second;   // Box once
Enum y = FooEnum.Second;   // Box again, to a separate object
Console.WriteLine(x == y); // False, because they're different references
Run Code Online (Sandbox Code Playgroud)

你可以Equals改用:

f => Equals(f.Enum, FooEnum.Second)
Run Code Online (Sandbox Code Playgroud)

...虽然每次迭代的拳击都不理想.您可以在Find通话前只装箱一次:

Enum boxed = FooEnum.Second;
fooFoundInstance = fooCollection.Find(f => Equals(f.EnumValue, boxed));
Run Code Online (Sandbox Code Playgroud)

在我看来,即便这样也不理想.我很少发现拥有类型的字段或属性很有用Enum.这可能是你的情况需要(我们没有足够的上下文就知道了),但在总体上会更好地使用混凝土枚举类型,如果在所有可能的.