5

I'm trying to make a List<byte> from a file that contains string (Hexadecimal) . the definition is :

List<byte> myArray = new List<byte>();

if I want to add my information directly I use something like this :

  myArray.Add(0xb8);

Note : Without any quotation or double-quotation .

The problem is when I want to do the same thing from file! Now I want to know what 0xb8's type is so I use the following code :

0xc3.GetType().ToString()

the result is : System.Int32 !!!!

but when I read strings from a file and use code like this , it give me the following error .

code :

 Line = "0xb8";
myArray.Add(Convert.ToInt32(Line));

Error :

Argument 1: cannot convert from 'int' to 'byte'

and it's clear . because the only overload of myArray gets only a byteas argumant. What makes thing so complicated for me is why it doesn't give me any error when I add a Int32 to myArray in myArray.Add(0xb8); .

I think it should be a form of byte ! maybe !

Why doesn't it give any errors and how can accomplish this scenario (I mean add byte from string to myArray ) ?

1
  • the result is : System.Int32 !!!! of course ... a number. What else could it be? Commented Jun 16, 2015 at 17:10

4 Answers 4

5

This works:

var list = new List<byte>();

byte byteValue = 0xb8;
list.Add(byteValue);

This doesn't ("cannot convert from 'int' to 'byte'"):

var list = new List<byte>();

int byteValue = 0xb8;
list.Add(byteValue);

Yet in both cases 0xb8 is recognized as System.Int32. So why does the compiler allow implicit conversion of an int to byte in the first example?

See C# spec 6.1.9 Implicit constant expression conversions:

A constant-expression (§7.19 [including literals]) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.

This exists because all integer literals are either (u)int or (u)long, as specified in 2.4.4.2 Integer literals.

Given 0 <= 0xb8 <= 255, the compiler allows the implicit conversion.

In your case, because of reasons explained by @usr, you'll need to do an explicit conversion:

myArray.Add((byte)Convert.ToInt32(Line, 16));
Sign up to request clarification or add additional context in comments.

Comments

4

0xb8 is an integer literal (like 1234). "0xb8" is a string literal (like "x"). There is no such thing as a hex literal in C#. It's an int literal in hex format. So that explains the trouble you had with the literals.

Not all of the string parsing functions support hex input. See this for how to parse a hex string.

When a parsing function gives you an int and you need to treat it as a byte, you can cast: (byte)myInt. This is safe because the parsed value is guaranteed to fit into a byte.

In some places the compiler is able to convert automatically for you if you have been using a constant such as 0xb8. Since you will not have that in practice (you are parsing a file) that case is not relevant for the final code. But this explains why that works.

2 Comments

his problem is that there is some intelligence in the compiler so that integral literals are converted to the right type by the compiler...
@xanatos right. Many things to explain here! What a surprisingly confusing problem for a beginner.
2

You can get rid of that compiler error by just casting the value to byte:

myArray.Add((byte)Convert.ToInt32(Line));

However, when you run that code you will get a different error:

Unhandled Exception: System.FormatException: Input string was not in a correct format.

That's because the Convert.ToInt32 method doesn't parse hexadecimal numbers out of the box.

You can specify the base when you convert the string to a number:

myArray.Add((byte)Convert.ToInt32(Line, 16));

1 Comment

Or you can save yourself the cast and use Convert.ToByte(Line, 16) instead...then if you happen to provide a Line of "0xF8C4" you can catch an OverflowException instead of just quietly truncating to 0xC4
2

How can accomplish this scenario (I mean add byte from string to myArray ) ?

List<byte> myArray = new List<byte>();
string Line = "0xb8";
myArray.Add(Convert.ToByte(Line, 16));

why it doesn't give me any error when I add a Int32 to myArray in myArray.Add(0xb8);

compiler can see that 0xb8 is in Byte values range

myArray.Add(0xb8);  // ok
myArray.Add(0xff);  // ok
myArray.Add(0x100); // cannot convert from int to byte

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.