locked
Variable Passing and Class RRS feed

  • Question

  • I have a question variable passing and efficiency in my program. This program I have loads in an array and assigns the array values to different variables (about 500). These variables are then used in a symbolic solver both inside of my main method, and other methods as well. Right now the optimization routine I use dictates that additional parameters get passed in via an object. Below I placed an example of what is going on.

    Would it be more efficient/better practice instead to create a class with all these variables and create a constructor so that they are only created once and pass by reference instead? During optimization the optimization method "testmethod" can be called upwards of 1000 times.


    // Orginal Code

    class testClass

    {

        static void main(double[] input)

        {

            double a = input[0];

            double b = input[1];

            object o = new object();

            o = input;
       
        }

        static void testmethod(object o)

        {

            double[] input = new double[((double[])(o[0])).Length];

            for (int i = 0;i<input.Length;i++)
       
            {

                input[i] = ((double[])(o[0]))[i];

            }

            double a = input[0];

            double b = input[1];

        }
    }

    // Proposed code

    public class myClass
    {

    public double a;
    public double b;

        public myClass(double[] input)
        {
           
            a = input[0];
            b = input[1];
        }
    }


    class testClass
    {

        static void main(double[] input)
        {
            testClass t = new testClass(input);
            double some_new_value = t.a + t.b;
            object[] o = new object[2];
            testmethod(ref o);
        }

        static void testmethod(ref object[] o)
        {
            ??? how do I now get to t.a, t.b, etc????
        }

    Thanks,
    Wednesday, July 6, 2011 1:45 PM

Answers

  • I think something like your proposed solution is the better option. To make it even better, you should give your doubles "real" names - instead of "a" and "b", call them something descriptive so it's clear exactly what is stored in them. The class could be implemented something like this:
    
    public static class StorageClass
    {
     public static double A = 0;
     public static double B = 0;
     public static double C = 0;
     public static object[] ObjectArray;
     // And so on...
    
     public static void Initialize(IEnumerable<double> values, object[] objArray)
     {
      A = values.ElementAt(0);
      B = values.ElementAt(1);
      C = values.ElementAt(2);
    
      objectArray = objArray;
     }
    }
    
    class TestClass
    {
     static void Main(string[] input)
     {
      List<double> inputs = new List<double>();
      double curItem;
      foreach (string arg in input)
      {
       if (Double.TryParse(arg, out curItem))
       {
        inputs.Add(curItem);
       }
       else
       {
        Console.WriteLine("One of the values provided was not a valid double.");
       }
      }
      object[] o = new object[2];
      StorageClass.Initialize(inputs, o);
     }
    }
    
    class CalculationClass
    {
     public void TestMethod()
     {
      double result = StorageClass.A * StorageClass.B;
      object test1 = StorageClass.ObjectArray[0];
     }
    }
    

    A few things to notice:
    1. Always validate the input. This checks to make sure everything passed in is actually a double and shows a message if one is not. Depending on your program, you may want to exit or throw an exception.
    2. You can store all of your information in a static class. You don't need to pass the object array by reference - just store that in the static class too. This cuts out all parameters. Each class only needs to be able to see that one static class, and they can see all of your calculation data.
    3. If your application is multi-threaded, this will need some additional work to make sure different threads don't stomp on each other and break the calculation. You will need to add locks in order to make it work correctly.
    4. For static classes, it's almost always a good idea to provide default values. In this case, set all of the doubles to 0, set the object array to a new empty array, etc.. Otherwise you can get exceptions if you try to access one of the fields before calling the Initialize method.


    • Edited by Tim Copenhaver Wednesday, July 6, 2011 3:06 PM
    • Proposed as answer by truptivd Thursday, July 7, 2011 11:38 AM
    • Marked as answer by Lie You Saturday, July 9, 2011 4:39 AM
    Wednesday, July 6, 2011 2:18 PM
  • Yes, sorry. That should be a capital A, B, C.

    And .ItemAt should be .ElementAt.

    Apparently I should really start typing examples into Visual Studio to make sure they're correct before entering them here...


    Check out My Blog for tech news, development tips, and other information for geeks like me.
    • Proposed as answer by truptivd Thursday, July 7, 2011 11:38 AM
    • Marked as answer by Lie You Saturday, July 9, 2011 4:38 AM
    Wednesday, July 6, 2011 3:02 PM

All replies

  • Use ref testClass t as another parameter.

    Thanks


    Anirban Bhattacharya (Lead Consultant - ESSPL)
    Wednesday, July 6, 2011 1:57 PM
  • Yes but my optimization method "testmethod" can only be called by testmethod(ref object[] o). I CAN NOT do have testmethod(ref object[] o, ref testClass t), if I could I think this would be much simipiler.
    Wednesday, July 6, 2011 2:02 PM
  • I think something like your proposed solution is the better option. To make it even better, you should give your doubles "real" names - instead of "a" and "b", call them something descriptive so it's clear exactly what is stored in them. The class could be implemented something like this:
    
    public static class StorageClass
    {
     public static double A = 0;
     public static double B = 0;
     public static double C = 0;
     public static object[] ObjectArray;
     // And so on...
    
     public static void Initialize(IEnumerable<double> values, object[] objArray)
     {
      A = values.ElementAt(0);
      B = values.ElementAt(1);
      C = values.ElementAt(2);
    
      objectArray = objArray;
     }
    }
    
    class TestClass
    {
     static void Main(string[] input)
     {
      List<double> inputs = new List<double>();
      double curItem;
      foreach (string arg in input)
      {
       if (Double.TryParse(arg, out curItem))
       {
        inputs.Add(curItem);
       }
       else
       {
        Console.WriteLine("One of the values provided was not a valid double.");
       }
      }
      object[] o = new object[2];
      StorageClass.Initialize(inputs, o);
     }
    }
    
    class CalculationClass
    {
     public void TestMethod()
     {
      double result = StorageClass.A * StorageClass.B;
      object test1 = StorageClass.ObjectArray[0];
     }
    }
    

    A few things to notice:
    1. Always validate the input. This checks to make sure everything passed in is actually a double and shows a message if one is not. Depending on your program, you may want to exit or throw an exception.
    2. You can store all of your information in a static class. You don't need to pass the object array by reference - just store that in the static class too. This cuts out all parameters. Each class only needs to be able to see that one static class, and they can see all of your calculation data.
    3. If your application is multi-threaded, this will need some additional work to make sure different threads don't stomp on each other and break the calculation. You will need to add locks in order to make it work correctly.
    4. For static classes, it's almost always a good idea to provide default values. In this case, set all of the doubles to 0, set the object array to a new empty array, etc.. Otherwise you can get exceptions if you try to access one of the fields before calling the Initialize method.


    • Edited by Tim Copenhaver Wednesday, July 6, 2011 3:06 PM
    • Proposed as answer by truptivd Thursday, July 7, 2011 11:38 AM
    • Marked as answer by Lie You Saturday, July 9, 2011 4:39 AM
    Wednesday, July 6, 2011 2:18 PM
  • Tim,

     

    Thanks the code is helpful. Few questions though when I try to implement this.

     

    In the initlizte function the a,b,c should A,B,C? I also have to declare public static double A = 0; so I can see "A" inside of the static initialize method.

     

    I also don't a .ItemAt

     

    Thanks,

    • Marked as answer by Lie You Saturday, July 9, 2011 4:38 AM
    • Unmarked as answer by Lie You Saturday, July 9, 2011 4:39 AM
    Wednesday, July 6, 2011 2:58 PM
  • Yes, sorry. That should be a capital A, B, C.

    And .ItemAt should be .ElementAt.

    Apparently I should really start typing examples into Visual Studio to make sure they're correct before entering them here...


    Check out My Blog for tech news, development tips, and other information for geeks like me.
    • Proposed as answer by truptivd Thursday, July 7, 2011 11:38 AM
    • Marked as answer by Lie You Saturday, July 9, 2011 4:38 AM
    Wednesday, July 6, 2011 3:02 PM
  • OK, Thanks for the help.
    Wednesday, July 6, 2011 3:17 PM