|
-
January 24th, 2009, 11:26 PM
#1
Casting int/double to generics?
I was having problem (see below "TROUBLE") casting int/double to generics ... This is what I intended to write,
Code:
public T RecursiveGetNextRandom<T>(T Max, T Min, List<T> lstExcludedNum)
{
int nNextNum = 0;
double dbNextNum 0;
T NextNum;
nMin = Convert.ToInt32(Min);
nMax = Convert.ToInt32(Max);
nNextNum = oRand.Next(nMin, nMax);
if(Max is double)
{
dbNextNum = oRand.NextDouble() * nNextNum;
NextNum = (T) dbNextNum; << TROUBLE: Can't cast to <T>!
} else if (Max is int) {
NextNum = (T) nNextNum; << TROUBLE: Can't cast to <T>!
}
return NextNum;
}
I ended up writing the following ugly code:
Code:
public static object RecursiveGetNextRandom(object Max, object Min, ArrayList lstExcludedNum)
{
object NextNum = 0;
Random oRand = new Random(Guid.NewGuid().GetHashCode());
double dbMin;
double dbMax;
int nNextNum;
if (Min == null)
{
Min = Int32.MinValue;
}
if (Max == null)
{
Max = Int32.MaxValue;
}
if (!(Max is int || Max is double))
{
...
}
dbMin = Convert.ToInt32(Min);
dbMax = Convert.ToInt32(Max);
SwapIfGreater(ref dbMin, ref dbMax);
nNextNum = oRand.Next(Convert.ToInt32(Math.Floor(dbMin)), Convert.ToInt32(Math.Floor(dbMax)));
if (Max is double)
{
NextNum = (double)nNextNum * oRand.NextDouble();
}
else if (Max is int)
{
NextNum = (int)nNextNum;
}
if (lstExcludedNum != null)
{
if (lstExcludedNum.Contains(NextNum))
{
RecursiveGetNextRandom(Max, Min, lstExcludedNum);
}
}
return NextNum;
}
Any suggestion? Thanks!~
-
January 25th, 2009, 12:01 AM
#2
Re: Casting int/double to generics?
How about make two different [static] method overloads?
Code:
public int RecursiveGetNextRandom(int max, int min, List<int> lstExcludedNum);
public double RecursiveGetNextRandom(double max, double min, List<double> lstExcludedNum);
-
January 25th, 2009, 08:28 AM
#3
Re: Casting int/double to generics?
you can use generics in an ugly way like this:
Code:
class Program
{
static void Main(string[] args)
{
Program prg = new Program();
test<Program>(prg);
}
static protected void test<T>(T str)
{
string str1 = str.ToString();
Console.WriteLine(str1);
//int x = 123;
//T y = (T)x;
Console.ReadKey(true);
}
}
how do you expect that compiler guess what cast you will do after initializing the generic and in this examle (that works fine) how do you expect that you cast an int to Program type.
uncomment the commented lines then you will see that you get compile-time error that is good becaue it prevents run-time errors.
Last edited by toraj58; January 25th, 2009 at 08:30 AM.
Please rate my post if it was helpful for you.  Java, C#, C++, PHP, ASP.NET
SQL Server, MySQL
DirectX
MATH Touraj Ebrahimi
[toraj_e] [at] [yahoo] [dot] [com]
-
January 25th, 2009, 12:35 PM
#4
Re: Casting int/double to generics?
Have you thought about using the Convert class ?
Code:
class RangedRandom<T>
where T : IConvertible
{
private Random _random = new Random();
private double _min;
private double _range;
private static readonly Type ElementType = typeof(T);
public RangedRandom(T min, T max)
{
_min = Convert.ToDouble(min);
_range = Convert.ToDouble(max) - _min;
}
public T Next()
{
double rand = _random.NextDouble();
double value = _min + (rand * _range);
return (T)Convert.ChangeType(value, ElementType);
}
}
class Program
{
static void Main(string[] args)
{
RangedRandom<int> random = new RangedRandom<int>(10, 50);
int count = 20;
while (count-- > 0)
{
Console.WriteLine(random.Next());
}
}
}
Note the RangedRandom class imposes the restriction that the type must implement IConvertible, so System.Convert will work.
Darwen.
Last edited by darwen; January 25th, 2009 at 01:04 PM.
-
January 25th, 2009, 01:06 PM
#5
Re: Casting int/double to generics?
where T : struct is good constraint for this case.
Please rate my post if it was helpful for you.  Java, C#, C++, PHP, ASP.NET
SQL Server, MySQL
DirectX
MATH Touraj Ebrahimi
[toraj_e] [at] [yahoo] [dot] [com]
-
January 25th, 2009, 04:57 PM
#6
Re: Casting int/double to generics?
where T : struct is good constraint for this case
Actually, no it's not because this will compile ok with a struct constraint, but will throw a compile error with a IConvertible constraint.
Code:
struct MyStruct
{
int a;
double b;
}
MyStruct min = new MyStruct();
MyStruct max = new MyStruct();
RangedRandom<MyStruct> rr = new RangedRandom<MyStruct>(min, max);
So an IConvertible constraint is better.
Darwen.
-
January 25th, 2009, 08:06 PM
#7
Re: Casting int/double to generics?
This is exactly what I was looking for, many Thanks Darwen!
-
January 25th, 2009, 08:30 PM
#8
Re: Casting int/double to generics?
Your welcome.
Remember the IConvertible constraint trick : I tend to find myself doing a lot of conversions between standard types (i.e. int, double etc) in my generic classes, and I find this is a good way of adding some type safety so that errors are picked up at compile time and not runtime.
Darwen.
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
|