How to prevent duplicate values in enum?

Viewed 8923

I wonder is there a way to prevent an enum with duplicate keys to compile?

For instance this enum below will compile

public enum EDuplicates
{
    Unique,
    Duplicate = 0,
    Keys = 1,
    Compilation = 1
}

Although this code

Console.WriteLine(EDuplicates.Unique);
Console.WriteLine(EDuplicates.Duplicate);
Console.WriteLine(EDuplicates.Keys);
Console.WriteLine(EDuplicates.Compilation);

Will print

Duplicate
Duplicate
Keys
Keys
6 Answers

Unit test that checks enum and shows which particular enum values has duplicates:

[Fact]
public void MyEnumTest()
{
    var values = (MyEnum[])Enum.GetValues(typeof(MyEnum));
    var duplicateValues = values.GroupBy(x => x).Where(g => g.Count() > 1).Select(g => g.Key).ToArray();
    Assert.True(duplicateValues.Length == 0, "MyEnum has duplicate values for: " + string.Join(", ", duplicateValues));
}

another solution to have unique values based on selected columns

var uniqueData = temp.Select(u => new tblschClassSchedule
            {
                TeacherName = u.TeacherName,
                SubjectName = u.SubjectName,

            }).Distinct() ;

this will get only 2 columns and only unique data for those columns

Just as addition, if you want to test ALL enums inside your project:

   [Test]
    public void EnumsDoNotHaveDuplicates()
    {
        IEnumerable<Type> enums = typeof(MyEnum).Assembly
            .GetTypes()
            .Where(t => t.IsEnum && t.IsPublic);

        foreach (Type t in enums)
        {
            MethodInfo method = typeof(EnumTestFixture).GetMethod(nameof(VerifyEnumHasNoDuplicates));
            MethodInfo generic = method.MakeGenericMethod(t);
            generic.Invoke(this, null);
        }
    }

    public void VerifyEnumHasNoDuplicates<T>()
    {
        T[] values = (T[])Enum.GetValues(typeof(T));
        Assert.IsTrue(values.Count() == values.Distinct().Count(), $"{typeof(T).Name} has duplicates!");
    }

Replace MyEnum with the any Type in the assembly that should be tested.

If you don't like the approach with Reflection or you prefer to have a test per enum (for whatever reason) you can still use the generic method:

VerifyEnumHasNoDuplicates<MyEnum>()

Related