CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Feb 2001
    Posts
    872

    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!~

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    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);

  3. #3
    Join Date
    Mar 2008
    Location
    IRAN
    Posts
    811

    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]

  4. #4
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    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.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  5. #5
    Join Date
    Mar 2008
    Location
    IRAN
    Posts
    811

    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]

  6. #6
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    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.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  7. #7
    Join Date
    Feb 2001
    Posts
    872

    Re: Casting int/double to generics?

    This is exactly what I was looking for, many Thanks Darwen!

  8. #8
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    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.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured