CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 30
  1. #1
    Join Date
    Aug 2010
    Posts
    13

    Why wont my enum be what it is ? I have to cast it to get the number

    I dont use enums or c# much but i thought they were to represent lists of numbers as actual values so your code could look nicer, similar to #define in c

    anyway i'm doin this , because i dont want to have/remember these values all the time

    public enum txMask : byte
    {
    battery = 0x01,
    accel = 0x02,
    sonar = 0x04,
    line = 0x08, //1000
    gps = 0x10, //10000
    move = 0x20, //100000
    test = 0x33
    }

    and then i try and use it in this function that accepts a byte
    setTXFlag(txMask.test);
    and i get the error
    Error 1 The best overloaded method match for 'JinxDebug.comm.setTXFlag(byte)' has some invalid arguments N:\SeniorProj\HighLevel\JinxDebug\JinxDebug\comm.cs 64 13 JinxDebug
    Error 2 Argument '1': cannot convert from 'JinxDebug.comm.txMask' to 'byte' N:\SeniorProj\HighLevel\JinxDebug\JinxDebug\comm.cs 64 23 JinxDebug

    but if i cast it like this
    setTXFlag((byte)txMask.test);

    it works great ... ??

    How can i avoid casting my enums all the time or should I be doing this another way ... I have quite a few enums that are very useful but assigning them ":int" and then still having to cast them seems dumb (I'm talking about another enum, that even though the "default" is int it still needs to be casted as int).

    thanks for your time

  2. #2
    Join Date
    May 2010
    Posts
    7

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    n <> np

  3. #3
    Join Date
    Jun 2008
    Posts
    2,477

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    You are making a faulty assumption here. An enumerated value is *not* it's underlying integral type, it is a true type. That means that there is no implicit conversion back and forth, and that is a good thing, trust me.

  4. #4
    Join Date
    Aug 2010
    Posts
    13

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    So what should i use in place of enumeration to have a simple '.' sort of system to call on hexadecimal numbers that i need to have set in one place and use in multiple places ?

  5. #5
    Join Date
    Jun 2008
    Posts
    2,477

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    You keep it an enumeration and use bitwise operators to do what you want. The problem here is that you are thinking of your enumeration only as a collection of bytes. It is more than that, it is a fully fledged type.

    Code:
    bool CheckForSonar( txMask value )
    {
        return (value & txMask.sonar) == txMask.Sonar; // or != 0, whatever
    }
    I would also point out that you are not following C# coding guidelines. Your types and public fields should begin with capital letters, i.e.,

    Code:
    public enum TXMask : byte
    {
        Battery = 0x01,
        Accel = 0x02,
        Sonar = 0x04,
        Line = 0x08,
        Gps = 0x10,
        Move = 0x20,
        Test = 0x33
    }
    Last edited by BigEd781; August 17th, 2010 at 12:22 AM.

  6. #6
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Quote Originally Posted by zonemikel View Post
    So what should i use in place of enumeration to have a simple '.' sort of system to call on hexadecimal numbers that i need to have set in one place and use in multiple places ?
    I'm under the impression that you want to use the enumeration elements as flags, with the ability to combine values? If so, you just need to add the [Flags] attribute, and you can use bitwise operators. But in your methods, you wouldn't have a byte parameter, but a TXMask parameter.
    One more thing: assuming that you are talking about flags, instead of hard-coding the value of TXMask.Test, it's better to use previously defined enum members. It's also a common practice to provide members representing potentially frequently used flag combinations.

    Code:
    [Flags]
    public enum TXMask : byte
    {
        Battery = 0x01,
        Accel = 0x02,
        Sonar = 0x04,
        Line = 0x08,
        Gps = 0x10,
        Move = 0x20,
        Test = Battery | Accel | Gps | Move,     // == 0x33
        SonarLine = Sonar | Line     // just to illustrate the point - maybe it doesn't make sense in your app
    };
    Then you can simply use the flags in a method, as BigEd781 instructed you.
    Search MSDN library for the FlagsAttribute class to learn more; the example provided there uses [FlagsAttribute] instead of [Flags], but this is equivalent.

    Quote Originally Posted by zonemikel View Post
    I dont use enums or c# much but i thought they were to represent lists of numbers as actual values so your code could look nicer, similar to #define in c
    As a side note, in C++ there are enumerations also, however, C++ allows for implicit conversions.

    As for C#:
    Quote Originally Posted by BigEd781 View Post
    [...] there is no implicit conversion back and forth, and that is a good thing, trust me.
    Exactly. The C# approach is better, but it's a bit hard to explain why, especially if you look at enumerations as if these were just some named numbers. Among other things, this prevents some nasty, hard to track-down bugs. And if you look at enums as concepts, then it makes sense not to be able to mix up two unrelated concepts together. For example, you can't write something like
    Fruit anApple = Toys.PlasticApple,
    and not get warned by the compiler.

  7. #7
    Join Date
    Aug 2010
    Posts
    13

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Ok thanks for all the help so far, and thanks for the coding guidelines info. I hate to say it ... but, you guys are getting all into the bit operators and such and thats not really at all my question.



    all i want is a method to be able to call numbers easily using words instead of the number ... i guess i could just make a function to do it for me ... like so

    // to remove the bit stuff i'll use phone numbers

    void int getNumber(string name)
    {
    if(name.compareto("mary")){ return 6748;}
    if(name.compareto("bob")){return 4432;}
    }
    then i can call stuff like this

    phoneCall(getNumber(mary));


    I know that function isnt right but you get the point, i just want to pass a word to functions and get it to resolve to a number. The enum works great because the '.' operation gives me my options, if i used a function that would not be the case.

    Is there anything wrong with just casting the enum ? So far it seems like the best option. I dont really know jack about c# so if there is a better way please let me know.

  8. #8
    Join Date
    Jun 2008
    Posts
    2,477

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Quote Originally Posted by TheGreatCthulhu View Post
    I'm under the impression that you want to use the enumeration elements as flags, with the ability to combine values? If so, you just need to add the [Flags] attribute, and you can use bitwise operators.
    It's kind of funny; I thought the same thing for a long time, but you don't actually have to use the flags attribute at all to use bitwise operators.

    The ToString implementation of your enum uses Flags, and so does Enum.IsDefined, Enum.Parse, etc. Try to remove Flags and look at the result of MyColor.Yellow | MyColor.Red; without it you get "5", with Flags you get "Yellow, Red". However, you do not need the attribute at all to treat your enum as a bit field. Kind of odd, but a common misconception.

    Quote Originally Posted by zonemikel View Post
    Ok thanks for all the help so far, and thanks for the coding guidelines info. I hate to say it ... but, you guys are getting all into the bit operators and such and thats not really at all my question.
    Then why are your values powers of two and named "Mask"? That makes it pretty clear that they are to be treated as bit fields. Looking at your latest example, using an enumeration there doesn't make sense at all, but neither does the code. I am at a loss.

    You are still thinking of an enum as a number and not a type. If you need a number, just use a number.
    Last edited by BigEd781; August 17th, 2010 at 12:09 PM.

  9. #9
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Quote Originally Posted by zonemikel View Post
    So what should i use in place of enumeration to have a simple '.' sort of system to call on hexadecimal numbers that i need to have set in one place and use in multiple places ?
    You can use a static class with constants defined.

    Code:
    public static class Mask
    {
      public const byte Battery = 0x01;
      public const byte Accel = 0x02;
      public const byte Sonar = 0x04;
      public const byte Line = 0x08;
      public const byte Gps = 0x10;
      public const byte Move = 0x20;
      public const byte Test = 0x33;
    }
    Given method defined as SetFlag( byte flag ), you would use it like:

    Code:
    SetFlag( Mask.Battery );
    or
    SetFlag( Mask.Battery | Mask.Line );
    While you *could* do it this way, it kind of defeats the purpose of type safety that the enum provides.

    So given
    Code:
    public enum TXMask : byte
    {
        Battery = 0x01,
        Accel = 0x02,
        Sonar = 0x04,
        Line = 0x08,
        Gps = 0x10,
        Move = 0x20
    }
    It's simple to write a byte converter:

    Code:
    byte GetByteFromTXMask( TXMask txMask )
    {
      return (byte) txMask;
    }
    or pass the enum directly to a method
    Code:
    void SetTXMask( TXMask txMask )
    {
      MethodThatTakesAByte( (byte) txMask );
    }

  10. #10
    Join Date
    Aug 2010
    Posts
    13

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Quote Originally Posted by Arjay View Post
    You can use a static class with constants defined.

    Code:
    public static class Mask
    {
      public const byte Battery = 0x01;
      public const byte Accel = 0x02;
      public const byte Sonar = 0x04;
      public const byte Line = 0x08;
      public const byte Gps = 0x10;
      public const byte Move = 0x20;
      public const byte Test = 0x33;
    }
    Oh wow thanks, I didnt think of that! Sorry to be so picky about this but i'm actually using this for several other things too.

    For example I've got my packets coming in as a string, and to index them i'm using rxPacket.number and stuff like that. I want to be sure i'm doing this right because its something I dont want to change later !

    Thanks i'll use a static class for all of them and i'll cap the first letter of public vars from now on. Sorry for all the confusion about bitwize stuff, I know you guys had the best of intentions.

  11. #11
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Quote Originally Posted by BigEd781 View Post
    It's kind of funny; I thought the same thing for a long time, but you don't actually have to use the flags attribute at all to use bitwise operators.

    The ToString implementation of your enum uses Flags, and so does Enum.IsDefined, Enum.Parse, etc. Try to remove Flags and look at the result of MyColor.Yellow | MyColor.Red; without it you get "5", with Flags you get "Yellow, Red". However, you do not need the attribute at all to treat your enum as a bit field. Kind of odd, but a common misconception.
    I was also pretty baffled by that, as it seemed that [Flags] had no real value; however take a look at the answer to this ("Flags" Attribute -- Useless???):
    Although C# happily allows users to perform bit operations on enums without the FlagsAttribute, Visual Basic does not. So if you are exposing types to other languages, then marking enums with the FlagsAttribute is a good idea; it also makes it clear that the members of the enum are designed to be used together.
    In the MSDN article on FlagsAttribute, it says "Languages vary in their use of bit fields compared to enumeration constants.".
    Microsoft really should have been more elaborate on that, because, if you read that out of the .NET multi-language support context, you're likely reaction would be: < Ahm... So what?

    I was always suspicious why would MS bother to write all those guidelines about when to use [Flags] anyway. It turns out that using it is meaningful if you write code that will be used by people developing with other .NET languages.

    Quote Originally Posted by zonemikel View Post
    Ok thanks for all the help so far, and thanks for the coding guidelines info. I hate to say it ... but, you guys are getting all into the bit operators and such and thats not really at all my question.



    all i want is a method to be able to call numbers easily using words instead of the number ... i guess i could just make a function to do it for me ... like so

    // to remove the bit stuff i'll use phone numbers

    void int getNumber(string name)
    {
    if(name.compareto("mary")){ return 6748;}
    if(name.compareto("bob")){return 4432;}
    }
    then i can call stuff like this

    phoneCall(getNumber(mary));


    I know that function isnt right but you get the point, i just want to pass a word to functions and get it to resolve to a number. The enum works great because the '.' operation gives me my options, if i used a function that would not be the case.

    Is there anything wrong with just casting the enum ? So far it seems like the best option. I dont really know jack about c# so if there is a better way please let me know.
    If you don't want to use enums as recomended, why don't you make a class or struct (if you have tiny set of data and related operations that are frequently used) instead. For example, call this class (or struct) Person, and define member fields to hold the number, name and other data, and methods or properties to get/set it.

    Then you would have
    Person mary = new Person("Mary", 6748);
    Person bob = new Person("Bob", 4432);

    //...

    // When you need to retrieve a number.
    PhoneCall(mary.Number);

    This way, you can store any number of persons in a collection, or do other neat stuff that classes enable you to do.
    But, I don't know how knowledgeable/skilled you are - maybe I'm going a bit overboard here?

    Anyway, you seem to just need to use the member access operator as a way to group related data. This can be done with a static class, as Arjay explained. However, depending on what you're trying to do, this may or may not be a good approach. What if you want to be able to dynamically add persons & numbers later on?
    What you're doing is, IMO, an example of how an I'll-try-to-make-you-program-OO language can be used in a non-OO way.

    BTW: Please use the [code][/code] tags around your code. It's explained somewhere in the forum's FAQ.
    Last edited by TheGreatCthulhu; August 17th, 2010 at 02:40 PM.

  12. #12
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Quote Originally Posted by zonemikel View Post
    Oh wow thanks, I didnt think of that! Sorry to be so picky about this but i'm actually using this for several other things too.

    For example I've got my packets coming in as a string, and to index them i'm using rxPacket.number and stuff like that. I want to be sure i'm doing this right because its something I dont want to change later !

    Thanks i'll use a static class for all of them and i'll cap the first letter of public vars from now on. Sorry for all the confusion about bitwize stuff, I know you guys had the best of intentions.
    Honestly, your still better off using an enum because it's type safe and you can't pass around invalid values (unless you are casting everywhere).

    Also, if you use an enum, you have the Enum class methods to help you with the parsing.

    Code:
    enum RxPacket
    {
      Number,
      String
    };
    
    var rxPacket = Enum.Parse( typeof( RxPacket ), incomingPacketType, true ) as RxPacket;
    With regard to the desire to not want to do this over, check out the recommended C# .net naming conventions. .Net uses PascalCase or camelCase depending on the object type, field, property, constant, and other naming rules.

  13. #13
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Quote Originally Posted by TheGreatCthulhu View Post
    This can be done with a static class, as Arjay explained. However, depending on what you're trying to do, this may or may not be a good approach.
    I don't recommend the static class approach as a replacement for enums.

    I remember when I first moved from C++ to C# years ago, I found the C# enums as a bit odd (and looked for the const class approach as well). However, over time I've come to learn how to use the C# enums and the Enum class methods. In the end for a fixed number of items, enum work better than the static class/const approach.

  14. #14
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Quote Originally Posted by Arjay View Post
    I don't recommend the static class approach as a replacement for enums.

    I remember when I first moved from C++ to C# years ago, I found the C# enums as a bit odd (and looked for the const class approach as well). However, over time I've come to learn how to use the C# enums and the Enum class methods. In the end for a fixed number of items, enum work better than the static class/const approach.
    I agree.
    However, I'm under the impression that the OP might not be dealing with a fixed number of items, but is just (unintentionally) misusing the language features. (The kind of the data is indicative: [a person] - [a phone number]) Thus my recommendation of the class/struct approach, but only the OP can determine if this is appropriate.

  15. #15
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Why wont my enum be what it is ? I have to cast it to get the number

    Agreed. Unless you have a fixed number of items, both the enum or the static class approach won't work very well.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured