-
August 16th, 2010, 04:52 PM
#1
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
-
August 16th, 2010, 05:03 PM
#2
Re: Why wont my enum be what it is ? I have to cast it to get the number
-
August 16th, 2010, 05:10 PM
#3
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.
-
August 16th, 2010, 08:50 PM
#4
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 ?
-
August 17th, 2010, 12:20 AM
#5
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.
-
August 17th, 2010, 06:40 AM
#6
Re: Why wont my enum be what it is ? I have to cast it to get the number
Originally Posted by zonemikel
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.
Originally Posted by zonemikel
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#:
Originally Posted by BigEd781
[...] 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.
-
August 17th, 2010, 11:42 AM
#7
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.
-
August 17th, 2010, 12:05 PM
#8
Re: Why wont my enum be what it is ? I have to cast it to get the number
Originally Posted by TheGreatCthulhu
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.
Originally Posted by zonemikel
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.
-
August 17th, 2010, 01:02 PM
#9
Re: Why wont my enum be what it is ? I have to cast it to get the number
Originally Posted by zonemikel
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 );
}
-
August 17th, 2010, 01:40 PM
#10
Re: Why wont my enum be what it is ? I have to cast it to get the number
Originally Posted by Arjay
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.
-
August 17th, 2010, 02:33 PM
#11
Re: Why wont my enum be what it is ? I have to cast it to get the number
Originally Posted by BigEd781
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.
Originally Posted by zonemikel
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.
-
August 17th, 2010, 02:58 PM
#12
Re: Why wont my enum be what it is ? I have to cast it to get the number
Originally Posted by zonemikel
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.
-
August 17th, 2010, 03:03 PM
#13
Re: Why wont my enum be what it is ? I have to cast it to get the number
Originally Posted by TheGreatCthulhu
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.
-
August 17th, 2010, 03:14 PM
#14
Re: Why wont my enum be what it is ? I have to cast it to get the number
Originally Posted by Arjay
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.
-
August 17th, 2010, 03:21 PM
#15
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|