如何防止枚举中出现重复值?

问题描述 投票:0回答:7

我想知道有没有办法阻止具有重复键的

enum
进行编译?

例如下面的

enum
将编译

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

虽然这段代码

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

将打印

Duplicate
Duplicate
Keys
Keys
c# .net enums
7个回答
35
投票

这是一个简单的单元测试来检查它,应该更快一点:

[TestMethod]
public void Test()
{
  var enums = (myEnum[])Enum.GetValues(typeof(myEnum));
  Assert.IsTrue(enums.Count() == enums.Distinct().Count());
}

22
投票

语言规范并未禁止这样做,因此任何符合要求的 C# 编译器都应该允许这样做。您始终可以调整 Mono 编译器来禁止它 - 但坦率地说,编写一个单元测试来扫描程序集的枚举并以这种方式强制执行会更简单。


16
投票

检查枚举并显示哪些特定枚举值具有重复项的单元测试:

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

2
投票

作为补充,如果您想测试项目中的所有枚举:

   [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!");
    }

MyEnum
替换为应测试的组件中的任何
Type

如果您不喜欢反射方法或者您更喜欢对每个枚举进行测试(无论出于何种原因),您仍然可以使用通用方法:

VerifyEnumHasNoDuplicates<MyEnum>()


0
投票
public bool ValidateAllDistinct(Type enumType)
{
    return !Enum.GetNames(enumType).All(outerName
        => Enum.GetNames(enumType).Any(innerName
            => innerName == outerName 
                ? true 
                : Enum.Parse(enumType, innerName) != Enum.Parse(enumType, outerName)));
}

我为您的单元测试提供了简单的测试方法。


0
投票

另一种基于所选列具有唯一值的解决方案

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

            }).Distinct() ;

这将仅获得 2 列,并且仅获得这些列的唯一数据


0
投票

2024 更新答案

您可以提高

CA1069
分析器的严重性,使编译器将其报告为错误并阻止编译。

dotnet_diagnostic.CA1069.severity = error

查看更多https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1069

© www.soinside.com 2019 - 2024. All rights reserved.