Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为枚举元素指定多个值_C#_Enums - Fatal编程技术网

C# 为枚举元素指定多个值

C# 为枚举元素指定多个值,c#,enums,C#,Enums,嗨,我现在有这个枚举 [Serializable] public enum Country { US = 1, Canada = 2, } 当我通常从数据库中获取整数时,我使用 (Country) Convert.ToInt32("1") 我现在在美国和加拿大有2个子区域,美国有1和2个子区域,加拿大有3和4个子区域。所以当我这么做的时候 (国家)Convert.ToInt32(“1”)或(国家)Convert.ToInt32(“2”)我应该得到我们的枚举。加拿大

嗨,我现在有这个枚举

[Serializable]
public enum Country
{
    US      = 1,
    Canada  = 2,
}
当我通常从数据库中获取整数时,我使用

(Country) Convert.ToInt32("1")
我现在在美国和加拿大有2个子区域,美国有1和2个子区域,加拿大有3和4个子区域。所以当我这么做的时候

(国家)Convert.ToInt32(“1”)
(国家)Convert.ToInt32(“2”)
我应该得到我们的枚举。加拿大3号和4号。我如何实现这一点

[Serializable]
public enum Country
{
    US      = 1,2
    Canada  = 3,4
}

像这样的。这可能不正确,但只是给你一个想法。

你必须这样做:

class Region
{
    static readonly RegionMap = new Dictionary<int,string>
    {
        { 1, "US" },
        { 2, "US" },
        { 3, "Canada" }
        { 4, "Canada" }
    }

    public static string GetRegion(int code)
    {
        string name;
        if (!RegionMap.TryGetValue(code, out name)
        {
            // Error handling here
        }
        return name;
    }
}

这是不可能的。你必须使用不同的值。如果名称相同,即

[Serializable]
[Flags]
public enum Country
{
    US      = 1,
    Canada  = 2,
    Northern = 4,
    Southern = 8
}

您可以这样做:
Countries=Country.US | Country.Northern
。如果没有,您需要找到另一种方法,可能是另一个属性,或者更好的方法,一个
位置
类。

可能是这样的吗

static Country ConvertRegionToCountry(string region)
{
    switch (region)
    {
        case "1":
        case "2":
            return Country.US;

        case "3":
        case "4":
            return Country.Canada;
    }
}

一个
enum
可能不是为此类问题建模的正确结构。

我建议创建一个类来表示国家信息,并提供与数字表示之间的转换方法。对于这样的问题,您还必须决定在将所选国家/地区实例转换为数值时使用的编码值

枚举对象模式可以作为建模此类情况的有用起点:

public sealed class Country
{
    // initialize appropriately in the constructor...
    private readonly int[] m_Values;
    private readonly string m_Name;

    // make the constructor private so that only this class can set up instances
    private Country( string name, int[] codes ) { ... }

    public static Country US = new Country("United States", new[]{ 1,2 } );
    public static Country Canada = new Country("Canada", new[] {3,4} );

    public static Country FromCode( int code ) { ... }
    public override string ToString() { return m_Name; }
    // ... etc...
}

根据您的示例,您还应该考虑是否需要将国家子区域建模为一流的实体,而不是简单地将其折叠到国家枚举的实现细节中。您是否应该这样做取决于您的需求和用例,因此只有您才能对此做出适当的决定。

啊,我只是使用了一个函数,而不是直接进行类型转换。比实现完全不同的东西容易得多。我已经有很多代码在这上面运行,所以不能改变它太多,但这里是我所做的

public Country GetCountryByTaxID(int taxID)
        {
            if (taxID == 3 || taxID == 4)
            {
                return Country.USA;
            }
            else 
            {
                return Country.Canada;
            }
        }  

对我来说,这就像一个设定问题,1&2在美国设定,3&4在加拿大设定。我认为有一些设置代码可以更好地对问题进行建模

继dtb的回答(以及那些等效的
if
建议)之后,我刚刚在我的应用程序名称空间中实现了一个“重写”版本的
System.Convert

public Country GetCountry(int a)
  {
    if (a == 1 || a == 2)
      {
        return Country.USA;
      }
      else if (a ==  4|| a == 3)
      {
         return Country.Canada;
      }
   }  
public static class Convert
{
    public static object ChangeType
        (object value, Type conversionType, IFormatProvider provider)
    {
        int country;
        if (conversionType == typeof(Country)
            && int.TryParse(value.ToString(), out country))
        {
            switch (country)
            {
                case 1:
                case 2:
                    return Country.US;
                case 3:
                case 4:
                    return Country.Canada;
            }
        }

        // For most cases, including any country unmatched above...
        return System.Convert.ChangeType(value, conversionType, provider);
    }
}

mscorlib.dll
Convert
类的原始方法现在必须以“
System.
”作为前缀,因此欢迎任何改进

我一直在寻找答案,因为我处于类似的情况(我需要枚举来定义游戏的菜单状态,其中每个状态更改都涉及到更改多个对象)。但我很难找到一个比我目前使用的更适合我需要的答案。所以我就把它留给那些觉得有用的人

只要处理枚举中的数值,就可以使用位移位的“复合”值。本质上

  • 2个字节作为ushort(
    0x1234
    as
    0x12
    0x34
  • 2 U作为uint32进行排序(
    0x12345678
    作为
    0x1234
    0x5678
  • 2个单元作为一个ulong(
    0x0123456789ABCDEF
    as
    0x01234567
    0x89ABCDEF
  • 8字节作为一个ulong(希望你明白我的意思)
等等

例如:

public enum CompoundEnum: ushort
{
    MenuOneOne = 0x101, // Can be split into bytes 0x1 and 0x1
    MenuOneTwo = 0x102, // Can be split into bytes 0x1 and 0x2
    MenuTwoOne = 0x201, // Can be split into bytes 0x2 and 0x1
}
我不太了解负数在不同系统中的存储方式,但我猜任何对负数存储有足够了解的人也可以轻松地“合成”符号值。此外,我个人的偏好是使用十六进制表示,因为这样更容易直观地读取单独的值


关于如何使用位移位(至少我希望它被称为位移位)计算值的内容已经足够多了,所以我将在这里链接这个答案:

感谢您的想法,我正在同一项目的其他情况下实现它。要改变现有的一个是非常痛苦的,所以我坚持快速修复。但是这个好多了。我发现这个是在找别的东西。这是我最明智的回答。当然,这个问题是5年半前提出的!
public enum CompoundEnum: ushort
{
    MenuOneOne = 0x101, // Can be split into bytes 0x1 and 0x1
    MenuOneTwo = 0x102, // Can be split into bytes 0x1 and 0x2
    MenuTwoOne = 0x201, // Can be split into bytes 0x2 and 0x1
}