473,503 Members | 1,648 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

type-casting System.Array of Enum values fails to "box"/convert correctly

Plater
7,872 Recognized Expert Expert
I ran into this interesting little issue when make a settings window for a SerialPort.

I have the following enum:
Expand|Select|Wrap|Line Numbers
  1. public enum BaudRates : int
  2. {
  3.   BR1200 = 1200, 
  4.   BR2400 = 2400, 
  5.   BR4800 = 4800, 
  6.   BR9600 = 9600, 
  7.   BR19200 = 19200, 
  8.   BR3800 = 38400, 
  9.   BR57600 = 57600, 
  10.   BR115200 = 115200, 
  11.   BR230400 = 230400,
  12. }
  13.  
I use the Enum class to retreive an array collection
Expand|Select|Wrap|Line Numbers
  1. Array BRs = Enum.GetValues(typeof(BaudRates));
  2.  
Now the thought is that I roughly have a BaudRate[] (instead of just returning an Object, they return an Array which all <type>[] inherit from?)
So I figure since my ENUM type is also an int, I'll do this:
Expand|Select|Wrap|Line Numbers
  1. int[] intBRs (int[])BRs;
  2.  
I was actually surprised it compiled and executed.
intBRs is now usable like a regular int[].
Here is where the confusion comes in. intBRs.GetType() shows type of BaudRate[] and not int[] as it was declared.
Looking at the debug window, it shows BR1200 BR2400 and etc anstead of 1200,2400, etc.
BUT I can say int a= intBRs[0]; and a has the value of 1200 just fine.

Now I know there is implicit conversion involved, but I want to use the intBRs as the datasource for a ComboBox and then set the SelectedItem to mySerialPort.BaudRate.
It cannot do this since the datasource is using BR1200, BR2400.
I can get around it by typecasting mySerialPort.BaudRate as a BaudRates, but I think the intBRs should have really been a int[] not a BaudRates[];

Work around:
Expand|Select|Wrap|Line Numbers
  1. int[] intBRs = (int[])Enum.GetValues(typeof(BaudRates));
  2. cbBaudRate.DataSource = (int[])intBRs;
  3. cbBaudRate.SelectedItem = (BaudRates)_port.BaudRate;
  4.  
This has the effect of the listbox showing the ENUM names and not the values, which is a bit more confusing when looking at the choices in the listbox

Does anyone have any thoughts on the boxing/unboxing issues
Jan 13 '11 #1
5 2705
Curtis Rutland
3,256 Recognized Expert Specialist
I think you'll just have to do the typecasting. According to the examples of Enum.GetValues, I thought you were right at first. But they explicitly type the iteration variable in the foreach. I did this:

Expand|Select|Wrap|Line Numbers
  1. Console.WriteLine("Implicit:");
  2. foreach(var v in Enum.GetValues(typeof(BaudRates)))
  3.     Console.WriteLine(v);
  4. Console.WriteLine("\nExplicit:");
  5. foreach(int i in Enum.GetValues(typeof(BaudRates)))
  6.     Console.WriteLine(i);
  7.  
  8.  
And got this result:

Implicit:
BR1200
BR2400
BR4800
BR9600
BR19200
BR3800
BR57600
BR115200
BR230400

Explicit:
1200
2400
4800
9600
19200
38400
57600
115200
230400
It appears that this is expected behavior.

If you are a LINQ kinda guy, there's another syntax for the cast:

Expand|Select|Wrap|Line Numbers
  1. var intBRs = Enum.GetValues(typeof(BaudRates)).Cast<int>().ToList();
Jan 13 '11 #2
Plater
7,872 Recognized Expert Expert
I am bothered by int[] intBRs not producing an int[].
I figured if it was going to ignore my requested type, I could do something like:
Expand|Select|Wrap|Line Numbers
  1. int[] test1 = ((int[])Enum.GetValues(typeof(BaudRates)));
  2. float[] test2 = ((float[])Enum.GetValues(typeof(BaudRates)));
  3.  
test1 creates that an object of type BaudRates[] and test2 throws an exception, cannot cast BaudRate[] to float[]...which means it IS trying to do casting and KNOWS that the BaudRate is also an int. Rather annoying.
I changed that enum to be :ulong and test1 failed up above, but another test using ulong[] worked the same way as int[] did previously.
I really think that is incorrect behavior. It tries to validate the type, but doesn't actually do the cast.
Jan 13 '11 #3
Curtis Rutland
3,256 Recognized Expert Specialist
Ok, I see what I missed the first time.

Expand|Select|Wrap|Line Numbers
  1. Array vals = Enum.GetValues(typeof(BaudRates));
  2. int[] ints = (int[])vals;
  3. Console.WriteLine("vals.GetType(): {0}", vals.GetType());
  4. Console.WriteLine("ints.GetType(): {0}", ints.GetType());
  5. Console.WriteLine("Print all vals:");
  6. foreach (var i in ints)
  7.     Console.WriteLine(i);
  8. Console.WriteLine("Print all ints:");
  9. foreach (var v in vals)
  10.     Console.WriteLine(v);
  11.  
vals.GetType(): HelloWorld.BaudRates[]
ints.GetType(): HelloWorld.BaudRates[]
Print all vals:
1200
2400
4800
9600
19200
38400
57600
115200
230400
Print all ints:
BR1200
BR2400
BR4800
BR9600
BR19200
BR3800
BR57600
BR115200
BR230400
Interesting. Apparently, casting the array didn't actually convert the values, it just boxes the array itself. So when you get a value via the the array, it implicitly casts it to the array type, but it's still stored as the original type.

Apparently that's the way arrays work. You're not performing a cast on each object, just the array object itself.

The Cast<T>() method I showed will actually cast each element, if you want to use that. Other than that, I'm not sure.
Jan 13 '11 #4
Plater
7,872 Recognized Expert Expert
I guess I need to move up in the .NET versions. .NET2.0 doesn't support using var or any of the linq stuff.
So i used object instead of var. Interesting, I got your results.
It must be that when I assigned it as the datasource, it lost its int[] boxing and just interpreted the BR1200 values. Still odd.
Jan 14 '11 #5
Curtis Rutland
3,256 Recognized Expert Specialist
Yeah, I don't know what I'd do without LINQ. Go crazy, probably. Var is usually just me being lazy, but when you use anonymous types, it's the only way to declare them.
Jan 14 '11 #6

Sign in to post your reply or Sign up for a free account.

Similar topics

30
21718
by: rh0dium | last post by:
Hi All, While I know there is a zillion ways to do this.. What is the most efficient ( in terms of lines of code ) do simply do this. a=1, b=2, c=3 ... z=26 Now if we really want some...
11
3789
by: jguilford | last post by:
I have created a SQL Stored Procedure that uses a Case statement to determine the Order By. For one of the Case statements I am trying to turn a Char field into Datetime in for the Order By,...
12
2271
by: Randell D. | last post by:
Folks, I have a form called "ourTestForm". Its a test form - nothing special - it contains five input tags - they are named one, two, three, four and five. The input tags are of type...
14
29295
by: Chris | last post by:
Hi, I try to print out truth-tables for an &&-operation using the following code, unfortunatly I get compiler errors : for ( byte i1=0; i1<=1; i1++) { for ( byte i2=0; i2<=1; i2++) { bool...
2
2071
by: 1388-2/HB | last post by:
I've got a small sockets application where I communicate with a web server via async sockets method. Using the ASCIIEncoding Class, I convert strings to byte arrays (and vice versa) in...
1
1836
by: gary | last post by:
In our site we are encountering problems with drop down boxes. We have a dropdown box & the ONChange event of which is fetching some data from a servlet. However when we use history back button ,...
12
1966
by: Astra | last post by:
Hi All I know this might sound weird, but I have a form where I ask the user to enter their email address in one text box and then again in a confirm email text box to make sure that they have...
2
2456
by: x | last post by:
hi i am a pilot by profession. i want to create a database of my logbook using ms access 2002. i am facing a problem regarding the format of time field. when i select "Data/Time" data type for my...
1
2447
by: The Eclectic Electric | last post by:
I'd be very grateful if anyone could help me with this. From my limited knowledge of Javascript I don't think it is possible, but I'll punt anyway. I downloaded and very slightly adapted this...
2
1709
by: veaux | last post by:
When I try to use the Link Table and select the type "ODBC" the browse window just disappears. If I select any other type, it behaves correctly. I tried repairing my office installation, but that...
0
7072
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7271
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7319
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7449
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4998
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3160
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3149
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
730
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
373
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.