为枚举元素分配多个值

发布于 2024-10-08 08:59:27 字数 547 浏览 4 评论 0原文

您好,我目前有这个枚举

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

当我通常从数据库获取整数时,我使用它将其转换为枚举

(Country) Convert.ToInt32("1")

我现在在美国和加拿大有 2 个子区域,1 和 1。 2 代表美国,3&4 代表加拿大。因此,当我执行

(Country) Convert.ToInt32("1")(Country) Convert.ToInt32("2") 时,我应该将枚举设置为 US。对于 3 & 4 加拿大。我如何实现这个?

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

像这样的东西。这可能是不对的,但只是为了给你一个想法。

Hi I have this enum currently

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

When I usually get the integer from the database I convert it to the enum using

(Country) Convert.ToInt32("1")

I now have 2 sub regions in US and Canada, 1 & 2 for US and 3&4 for canada. So when I do

(Country) Convert.ToInt32("1") or (Country) Convert.ToInt32("2") i should get the enum to be US. and for 3 & 4 Canada. How do i implement this?

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

Something like this. This is probably not right but just to give you an Idea.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

各自安好 2024-10-15 08:59:27

枚举可能不是模拟此类问题的正确构造。

我建议创建一个类来表示国家/地区信息,并提供与数字表示形式相互转换的方法。对于此类问题,您还必须决定将选定的 Country 实例转换为数值时将使用什么编码值。

枚举对象模式可以作为对这种情况进行建模的有用起点:

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...
}

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

An enum may not be the right construct to model this kind of problem.

I would suggest creating a class to represent country information, and provide methods the convert to and from numeric representations. With problems like this, you also have to decide what coding value you will use when converting a selected Country instance into a numeric value.

The Enum Object pattern can be helpful starting point for modeling this kind of situation:

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...
}

Based on your example, you should also consider whether you need to model Country sub-regions as first-class entities, rather than simply folding them into the implementation details of your Country enumeration. Whether you should do this or not depends on your requirements and use cases, so only you can make an appropriate decision on that.

永不分离 2024-10-15 08:59:27

您必须执行以下操作:

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

然后根据数据库中的值查找字符串:

string region = Region.GetRegion(dbVal);

You will have to do something like this:

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

Then look up the string based on the value from the database:

string region = Region.GetRegion(dbVal);
淡淡の花香 2024-10-15 08:59:27

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

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

您可以这样做:Countries = Country.US |国家/地区.北部。如果没有,您需要找到另一种方法,可能是另一个属性,甚至更好的是 Location 类。

This is not possible. You'd have to use seperate values then. If the names are the same, ie.

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

You could do this: Countries = Country.US | Country.Northern. If not, you need to find another way, possible another property or even better, a Location class.

落叶缤纷 2024-10-15 08:59:27

也许是这样的?

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

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

Maybe something like this?

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

        case "3":
        case "4":
            return Country.Canada;
    }
}
兔姬 2024-10-15 08:59:27

啊我只是使用了一个函数而不是直接类型转换。比实施完全不同的东西要容易得多。我已经在上面运行了很多代码,所以无法对其进行太多更改,但这就是我所做的。

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

Ah I just used a function instead of directly typecasting. Far more easier than to implement something entirely different. I already have lot of code running on this so cant change it much but here is what I did.

public Country GetCountryByTaxID(int taxID)
        {
            if (taxID == 3 || taxID == 4)
            {
                return Country.USA;
            }
            else 
            {
                return Country.Canada;
            }
        }  
七颜 2024-10-15 08:59:27
public Country GetCountry(int a)
  {
    if (a == 1 || a == 2)
      {
        return Country.USA;
      }
      else if (a ==  4|| a == 3)
      {
         return Country.Canada;
      }
   }  
public Country GetCountry(int a)
  {
    if (a == 1 || a == 2)
      {
        return Country.USA;
      }
      else if (a ==  4|| a == 3)
      {
         return Country.Canada;
      }
   }  
懵少女 2024-10-15 08:59:27

这对我来说就像一个设定问题,其中 1 & 2 位于集合 us 和 3 & 中。 4 位于加拿大。 代码项目上有一些设置代码,我认为它们可以更好地模拟问题。

This seams like a set problem to me where 1 & 2 are in the set us and 3 & 4 are in the set Canada. There is some set code on code project which I think better models the problem.

难以启齿的温柔 2024-10-15 08:59:27

除了 dtb 的回答(以及那些等效的 if 建议)之外,我刚刚在应用程序的命名空间中实现了 System.Convert 的“覆盖”版本:

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.”为前缀,因此欢迎任何改进!

Further to dtb's answer (and those equivalent if suggestions), I just implemented an 'overridden' version of System.Convert in my application's namespace:

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

Original methods of the mscorlib.dll Convert class must now be prefixed with "System." of course, so any refinements would be welcome!

素罗衫 2024-10-15 08:59:27

我一直在寻找答案,因为我处于类似的情况(我需要枚举来定义游戏的菜单状态,其中每个状态更改都涉及更改多个对象)。但我很难找到比我目前使用的更适合我需求的答案。因此,我将把它留在这里,供任何认为有用的人使用。

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

  • 2 个字节作为 ushort(0x1234 作为 0x120x34
  • 2 个 ushort 作为 uint32(0x12345678 作为0x12340x5678)
  • 2 个 uint 作为 ulong(0x0123456789ABCDEF0x012345670x89ABCDEF
  • 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
}

我不太了解负值如何存储在不同的系统中,但我猜任何对负值存储有足够了解的人也可以轻松地“复合”有符号值。另外,我个人偏好使用十六进制表示,因为这样更容易直观地读取单独的值。

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

I was looking for an answer since I am in a similar situation (I need enums to define menu states for a game where each state change involves changing multiple objects). But I'm having a hard time finding an answer that suits my needs better than what I'm using currently. So I'm just going to leave it here for whoever finds it useful.

As long as you're dealing with numerical values in your enum, you can use bit-shifted 'compound' values. Essentially,

  • 2 bytes as a ushort (0x1234 as 0x12 and 0x34)
  • 2 ushorts as a uint32 (0x12345678 as 0x1234 and 0x5678)
  • 2 uints as a ulong (0x0123456789ABCDEF as 0x01234567 and 0x89ABCDEF)
  • 8bytes as a ulong (you get my point, hopefully)

and so on.

An example:

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
}

I'm not very knowledgeable about how negative values are stored in different systems, but I'm guessing anyone with sufficient knowledge about storage of negatives can easily 'compound' signed values as well. Also, my personal preference is representation using hexadecimal, as this way it's easier to visually read the separate values.

There's enough about how to calculate values using bit-shifting (at least I hope it's called bit-shifting), so I'm just going to link this answer here: https://stackoverflow.com/a/3099367/1543356

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文