【问题标题】:Can you assign an enum value to an enum in C# [closed]您可以将枚举值分配给 C# 中的枚举吗[关闭]
【发布时间】:2021-12-08 01:58:17
【问题描述】:

我想为名称列表创建一个枚举,并为名称所属的类别列表创建另一个枚举。我看到了这篇出色的帖子here,它在将字符串分配给枚举方面做得很好,但我想要做的类似于以下内容:

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

public enum Category
{
    Category1,
    Category2,
    Category3
}

然后我会使用他们在我上面提到的帖子中创建的扩展来查找当前名称的类别等。有没有办法在 C# 中做到这一点?

【问题讨论】:

  • 如该帖子所示,您可以创建自己的属性并将其附加到枚举成员。您在执行该操作时遇到问题吗?
  • @gunr2171 我对代码的主要问题是,因为我有几百个具有相同类别的名称,所以对我来说将类别也设为枚举并且目前使用此代码是有意义的您只能为类别属性传入一个字符串
  • 枚举用于固定的硬编码条目。您确定枚举是名称和类别列表的合适用例吗?你不能改变你的类别属性来接受一个枚举值而不是一个字符串吗?

标签: c# enums


【解决方案1】:

Name Enum 有名字,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;
}

【讨论】:

  • 这是很棒的代码。我想知道您是否知道是否可以反过来并传入类别以获取具有该类别的名称列表
  • @DarthVegan 添加了按类别获取名称列表的方法
【解决方案2】:

当您创建自己的属性时,您可以传递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;
    }
}

【讨论】:

  • 我认为 Attribute.GetCustomAttribute(type.GetType(), typeof(CategoryAttribute)) 的第一个参数不正确。我们已经有了上一行中的类型。但我认为我们实际上需要获取成员名称。看我的回答
【解决方案3】:

稍加注意,你可以给每个枚举的整数值一个特定的含义;

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

【讨论】:

    猜你喜欢
    • 2021-10-21
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多