你能在 C# 中为枚举分配一个枚举值吗

Can you assign an enum value to an enum in C#

我想为名称列表创建一个枚举,为名称所属的类别列表创建另一个枚举。我看到这个优秀的 post here 在将字符串分配给枚举方面做得很好,但我想做的类似于以下内容:

public enum Name
{
    [CategoryAttribute(Category.Category1)]
    Name1,
    [CategoryAttribute(Category.Category2)]
    Name2,
    [CategoryAttribute(Category.Category3)]
    Name3
}

public enum Category
{
    Category1,
    Category2,
    Category3
}

然后我会使用他们在我上面提到的 post 中创建的扩展,以便能够查找当前名称的类别等。有没有办法在 C# 中执行此操作?

当您创建自己的属性时,您可以传递 Category enum 本身,而不是传递字符串。请参阅下面我的实现:

public enum Category
{
    Category1,
    Category2,
    Category3
}

public enum Name
{
    [Category(Category.Category1)]
    Name1,

    [Category(Category.Category2)]
    Name2,

    [Category(Category.Category3)]
    Name3
}

public class CategoryAttribute : Attribute
{
    public Category category;

    public CategoryAttribute(Category category)
    {
        this.category = category;
    }
}

public static class Extentions
{
    public static Category GetCategory(this Name obj)
    {
        var type = obj.GetType();
        var attr = (CategoryAttribute) Attribute.GetCustomAttribute(type.GetType(), typeof(CategoryAttribute));
        return attr.category;
    }
}

稍加注意,您可以为每个枚举的整数值赋予特定含义;

public enum Name
{
    // Category 1
    Name1 = (int)Category.Category1,
    Name2,
    Name3,

    // Category 2
    Name4 = (int)Category.Category2,
    ...
}

public enum Category {
    Category1 = 1000,
    Category2 = 2000,
}

public Category GetCategory(Name name) => (Category)((int)name - ((int)name % 1000));

带名称的 Name 枚举,Name4 是没有类别属性的成员示例

public enum Name
{
    [Category(Category.Category1)]
    Name1,
    [Category(Category.Category2)]
    Name2,
    [Category(Category.Category3)]
    Name3,
    Name4
}

public enum Category
{
    //default value to return from GetCategory if no Category is assigned
    None,

    Category1,
    Category2,
    Category3
}

public class CategoryAttribute : Attribute
{
    public Category Category { get; set; }

    public CategoryAttribute(Category cat)
    {
        Category = cat;
    }
}

e 参数中传递的值是枚举的基础类型的值,在本例中为 int。为了获取赋值的属性,我们首先需要获取int关联的名称,然后根据名称查找属性。

public static class NameMethods
{
    public static Category GetCategory(this Name e)
    {
        var name = Enum.GetName(typeof(Name), e);
        var  member = e.GetType().GetMember(name).FirstOrDefault();
        var attr = Attribute.GetCustomAttribute(member, typeof(CategoryAttribute)) as CategoryAttribute;

        return attr?.Category ?? Category.None;
    }
}

运行 具有四个不同类别的代码

public static class Program
{
    static void Main(string[] args)
    {
        var result = Name.Name1.GetCategory(); //Category1
        var result1 = Name.Name2.GetCategory(); //Category2
        var result2 = Name.Name3.GetCategory(); //Category3
        var result3 = Name.Name4.GetCategory(); //None
    }
}

如果您想换一种方式获取已分配给特定类别的名称列表,则可以使用此方法。请注意,此代码只允许为每个名称分配一个类别。

public static List<Name> GetNames(Category category)
{
    //Find all Members of Name Enum Type that have a categoryAttribute with the Category property assigned to the category parameter.
    var members = typeof(Name).GetMembers().ToList();
    var result = new List<Name>();
    foreach (var member in members)
    {
        //get attributes for member
        var categoryAttribute = Attribute.GetCustomAttribute(member, typeof(CategoryAttribute)) as CategoryAttribute;
        if (categoryAttribute != null && categoryAttribute.Category == category)
        {
            //use the member name to get an instance of enumerated type.
            Enum.TryParse(member.Name, out Name name);
            result.Add(name);
        }
    }

    return result;
}