[SPAM] - Re: [Mono-devel-list] DataSetHelper Class and Mono problems? - Email found in subject

Jon Benson Jon at destra.com
Sun Oct 17 22:51:22 EDT 2004


Thanks for the detailed explanation.  Even as a relative newbie to C# I
think I actually follow that.  :)

In short this means the Add function within the DataSetHelper class is
only valid for one type of object anyway?  :(

My test scenario was sadly not exactly the same as the code I was using.
With some debugging I discovered that under .NET the object being passed
to the Add function, in my original code, was being passed as whatever
type the DataColumn in the DataTable was specified as (I was originally
using Int32 but changed it to Decimal) but under Mono it is ending up as
System.String regardless of it's original type.


Thanks,

Jon

-----Original Message-----
From: Jonathan Pryor [mailto:jonpryor at vt.edu] 
Sent: Friday, 15 October 2004 9:26 PM
To: Jon Benson
Cc: Mono Development List
Subject: [SPAM] - Re: [Mono-devel-list] DataSetHelper Class and Mono
problems? - Email found in subject

On Thu, 2004-10-14 at 23:09, Jon Benson wrote:
<snip/>
> However I run in to a problem with one of the functions throwing an 
> exception under Mono.  I've created a bit of test code to reproduce 
> this
> exception:
> Unhandled Exception: System.InvalidCastException: Cannot cast from 
> source type to destination type.
> in <0x00085> Test.TestClass:Add (object,object) in <0x0004e> 
> Test.TestClass:Main (string[])

You're getting an exception because your code is buggy. :-)

You're passing boxed ints to Add, but Add casts them to decimal.  A
boxed int can't be cast to a decimal.  For example:

	object boxed_int = 42;
	int i = (int) 42; // unbox: valid
	decimal d = 42;   // calls Decimal.implicit operator Decimal
(int)
	decimal d2 = (decimal) boxed_int;
		// runtime cast check.  
		// boxed_int.GetType() != typeof(Decimal), so an 
		// InvalidCastException is thrown.

The last cast is precisely what your program does.  As Umadevi
mentioned, it also fails on .NET.

It fails because runtime casts don't look for any type conversion
operators that the types define, such as "implicit operator Decimal (int
value)''.  Such operator functions calls are generated by the compiler,
not the runtime.  Thus, to convert a boxed int into a decimal, you'd
need two casts:

	decimal d = (decimal) (int) boxed_int;

> Sample code to reproduce the exception:
> using System;
> 
> namespace Test
> {
>    class TestClass
>    {
>       [STAThread]
>       static void Main(string[] args)
>       {
>          int i1 = 34; int i2 = 8;
> 
>          int i3 = (int)((decimal)i1 + (decimal)i2);
>          Console.WriteLine(i3.ToString());
> 
>          i3 = (int)(TestClass.Add(i1, i2));

Notice that i1 and i2 are of type int, so  you're passing boxed ints.

>          Console.WriteLine(i3.ToString());
>       }
> 
>       private static object Add(object a, object b)
>       {
>           //Adds two values - if one is DBNull, then returns the other
>           if (a is DBNull)
>               return b;
>           if (b is DBNull)
>               return a;
>           return ((decimal)a + (decimal)b);

Here you cast the boxed ints to a decimal.  Thus, an
InvalidCastException.

>       }
>    }
> }

 - Jon





More information about the Mono-devel-list mailing list