当它们共享整数值时获取原始唯一的 C# Enum 对象

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

如果我有一个 C# 枚举,其中两个对象映射到相同的整数值,是否有任何可能的方法来获取每个唯一的

Enum
对象?我尝试过的每种方法仅返回一个对象 - 这可能是该值第一次出现。

假设我定义了以下枚举,其中两个对象由于某种原因映射到相同的整数值。

public enum Testing
{
    [Description("This is Value1")]
    [Display(Name = "Value 1")]
    Value1 = 0,

    [Description("This is Value2")]
    [Display(Name = "Value 2")]
    Value2 = 1,

    [Description("This is Value3")]
    [Display(Name = "Value 3")]
    Value3 = 2,

    [Description("This is Value4")]
    [Display(Name = "Value 4")]
    Value4 = 0
}

在这种情况下,根据某些标准,我需要

Value1
Value4
都映射到积分值 0。这两个值的功能将在应用程序中产生相同的行为。这两个选项存在背后的原因不一定相关,但举例来说,我希望用户非常清楚 Value1 和 Value4 都映射到 0,即使它们不一定是相同的选项。

然后我想在运行时动态加载

Testing
类型的枚举对象。对于两个选项不映射到相同整数值的枚举,有很多方法可以做到这一点。使用
Enum.GetValues()
Enum.GetNames
,使用反射获取
FieldInfo[]
,然后迭代每个并调用
FieldInfo.GetValue()
。这些都正常工作......但是当两个 Enum 对象映射到相同的整数值时,使用任何返回 Enum 对象的方法都会为
Value1
Value4
返回相同的对象 - 可能
Value1
.

但是,在本例中,我为每个对象设置了特定属性。我想以允许我在运行时利用这些属性的方式加载对象。也许我想在下拉列表中显示每个选项,并希望使用

Display
属性中的名称来提供更多用户友好的字符串,或者能够在每个选项的工具提示中提供额外的冗长描述。

我尝试了以下方法,但没有效果,它们都会导致返回

Value1
Value4
对象,这不可避免地导致访问
Value1
的自定义属性,而不是
Value4

foreach (Enum value in Enum.GetValues(type))
{
    // value for Value4 is Value1...
}

foreach (string name in Enum.GetNames(type))
{
    Enum value = (Enum)Enum.Parse(type, name);
    // value for Value4 is Value1...
}

foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Public | BindingFlags.Static))
{
    Enum value = (Enum)fieldInfo.GetValue(null);
    // value for Value4 is Value1...
    // fieldInfo DOES have the custom attributes for Value4 and DOES have the original name Value4
}

在 C# 中是否有任何可能的方法来保留

Value4
的原始枚举对象?从技术上讲,我可以存储
FieldInfo
对象,但我宁愿(并且需要)存储 Enum 对象。我很惊讶,甚至没有通过反射迭代字段信息,我肯定有
Value4
字段也不会返回该对象。

c# .net enums custom-attributes system.reflection
1个回答
0
投票

你所要求的是不可能的。一个示例程序可以在这里快速演示该问题:

using System;

public enum ExampleEnum
{
    SomeValue = 1,
    AliasValue = 1
}

public class Program
{
    public static void Main()
    {
        var x = ExampleEnum.AliasValue;
        Console.WriteLine(x.ToString());
    }
}

您自然会期望该程序将“AliasValue”写入控制台,但您却看到“SomeValue”。其原因很容易理解 - 枚举在幕后被实现为整数。当从整数返回 Enum 成员时,C# 将只选择第一个具有相应值的成员。 C# 仅保留整数值,如果两个枚举成员具有相同的值,则应假定它们也具有相同的行为。

在这种情况下,根据某些标准,我需要 Value1 和 Value4 都映射到整数值 0。这两个值的功能将在应用程序中产生相同的行为。这两个选项存在背后的原因不一定相关,但举例来说,我希望用户非常清楚 Value1 和 Value4 都映射到 0,即使它们不一定是相同的选项。

我建议您重新考虑这种方法。如果行为没有差异,那么标签是否“自动更正”到第一个选项应该没有关系。如果它确实很重要,那么听起来好像存在差异,并且它们不应该具有相同的值。


由于仍然存在一些混乱,我将在示例中添加更多内容。您自己不会在整数和枚举之间进行转换,但 C# is 在幕后做类似的事情。它可能会帮助您假设“Enum”只是“整数”类型包装器的语法糖,并且每个成员都转换为“const int”字段:

public record struct ExampleEnum(int value)
{
    public static readonly ExampleEnum SomeValue = new(1);
    public static readonly ExampleEnum AliasValue = new(1);

    public string ToString() => value switch =>
    {
        1 => "SomeValue",
        _ => value.ToString(),
    };
}

public class Program
{
    public static void Main()
    {
        var x = ExampleEnum.AliasValue;
        Console.WriteLine(x.ToString());
    }
}

*这不是完全幕后发生的事情,但它是一个近似值

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