Specified cast is not valid

S

simon

I declare variable as int16:

int16 hourS;

then I open dataReader and set the variable:

hourS=rdr.getInt16(1);

but I get an error when I start the page:

"Specified cast is not valid."

I don't understand why?
Both sides are defined as int16, also the value which reader returns is
small, like 5 for example.

I know, I can use convert function:

hourS=convert.Toint16(rdr.getInt16(1));

it works, but doesn't make sense.

Regards,S
 
G

Guest

The GetInt16() function returns 'short' which is a C# datatype whereas Int16
is a .net framework's common data type. Although the sizes of both data types
may be the same they are considered as different data types since C# supports
strong type checking.
 
S

simon

Thank you.

What is the best solution here?

One option is to declare variable as int32 and no conversion function
needed(sql always returns int32):

int32 hourS;
hourS=rdr.getInt32(1);

or:

int16 hourS;
hourS=convert.Toint16(rdr.getInt32(1));

So, in first example I don't need to call convert function but on the other
hand, I spent twice as much memory as with int16.

When work with int16 type there is also one other problem:

int16 a,b;

b=1;
a=b+1; //this wont work

I must always write int16 in front of:
a=(int16)(b+1);

When using int32(or int), everything works:

int32 a,b;
b=1;
a=b+1;

So, what do you suggest?

Work with short inseat of int16 in my example?



regards,
Simon
 
B

Bjorn Abelli

...
The GetInt16() function returns 'short' which is a C# datatype
whereas Int16 is a .net framework's common data type.
Although the sizes of both data types
may be the same they are considered as different data types since
C# supports strong type checking.

Hold your horses!

"Int16" and "short" are the same datatype. "short" is simply an alias for
Int16 and are considered the *same* datatype.


// Bjorn A
 
B

Bjorn Abelli

...
Thank you.

Wait a minute before you thank Sameeksha, as he's actually wrong.

"short" and Int16 are simply the same datatype, so your problem is not
there.

In the framework Int16 is the datatype, and "short" is an alias for that
datatype.

So which one you're writing in the source code doesn't really matter, but
*casing* does matter!

There's no type "int16"...
What is the best solution here?

I would suggest that you use "short" instead of "Int16", *but* that's if it
really is the right type to use in your explicit scenario.

My guess is that the error of "casting" actually isn't related to *that*
casting, but to the internal casting done when you do the *reading*.

What DB are you using, and what datatype does the field have.

E.g. if the field is of type "byte" in an Access-db, you can get the casting
error if you try to read it with GetInt16 instead of GetByte.


// Bjorn A
 
J

Jon Skeet [C# MVP]

Sameeksha said:
The GetInt16() function returns 'short' which is a C# datatype whereas Int16
is a .net framework's common data type. Although the sizes of both data types
may be the same they are considered as different data types since C# supports
strong type checking.

No, that's not true - they are absolutely the same type. "short" is
just a shorthand for Int16, as per the C# specification, section 11.1.3
in ECMA numbering.
 
S

simon

Thank you Bjorn for your explanation.

I know about casing and it's not the problem. It's just my inconsistent when
writing to this post.

In code I have Int16.

My select statement is like this for example:

SELECT datepart(hh,getdate())

And select returns sql int data type, which is the same as Int32 in C#.

But number is always small, from 0 to 23, so why use Int32 dataType and use
additional memory?

Because of that, I use Int16 dataType:

Int16 hourS;
hourS=Convert.Toint16(rdr.getInt32(1));

It works.

But it brings a lot of work.

Everywhere in code where I use Int16 variables I must write (Int16) in front
of line, for example:

hours=(Int16)(hourS+1);

If i work with Int32 variables, no additional coding is needed:

Int32 hourS;
hourS=hourS+1;

and also no call to conversion function is needed (so, less processor work):

hourS=rdr.getInt32(1);

So these are the reasons to use Int32 DataType.

You suggest short?

short hourS;

Why?

If i use short:

hourS=hourS+1;

I also get an error:

"Cannot implicitly convert type 'int' to 'short'. An explicit conversion
exists (are you missing a cast?) "

So; I still have to write like this:

hourS=(short)(hourS+1)

and i still use procesor work with calling conversion functions:

hourS=Convert.ToInt16(rdr.getInt32(1));

So, in this case the Short is the right answer?

Simon
 
B

Bjorn Abelli

...
Thank you Bjorn for your explanation.

You're welcome.
And select returns sql int data type,
which is the same as Int32 in C#.

Okej, so you should use GetInt32 as that *is* what you're reading from the
db...
But number is always small, from 0 to 23, so why use
Int32 dataType and use additional memory?

Because you can't change the datatype of what you're reading... ;-)

Well, actually I'd guess that you possibly *could* do that in some way, if
you encapsulate the reading in a stored procedure in the db, which in turn
"casts" it somehow to a short instead of an int, but my guess is that it
would be overkill...
Because of that, I use Int16 dataType:

Int16 hourS;
hourS=Convert.Toint16(rdr.getInt32(1));

It works.

This should probably also work:

Int16 hours = (Int16) rdr.getInt32(1);

or

short hours = (short) rdr.getInt32(1);
But it brings a lot of work.

Not explicitly that, but other things might...
Everywhere in code where I use Int16 variables I must
write (Int16) in front of line, for example:

hours=(Int16)(hourS+1);

If i work with Int32 variables, no additional coding is needed:

Int32 hourS;
hourS=hourS+1;

and also no call to conversion function is needed (so, less processor
work):

hourS=rdr.getInt32(1);

Yes and No.

If hourS is declared as an Int16, hourS is *always* an Int16, no matter how
you assigned the value to it. However, the problem *there* lies in what type
a *literal* is of...

In your code:

hourS = hourS + 1;

....whether or not hourS is of type short (Int16), you also have the literal
1, which default is of type int (Int32)! Therefore, you *still* need to cast
the expression if you use short variables.
So these are the reasons to use Int32 DataType.

You suggest short?

As I said before, Int16 and "short" are interchangable in your code, as
short simply is an alias for Int16.

Personally, I prefer short before Int16, because I switch a lot between C#,
C++ and Java. It makes a lot of things easier for me...

In this specific case, I would suggest you use int instead of Int32.

That's the only way you can eliminate the casts of such expressions as
mentioned above...

If you think that it would make your program "too big" because of excessive
use of memory, then you're stuck with the casting, when you use such
literals in the expressions...


// Bjorn A
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top