tags:

views:

373

answers:

4

I am in need of some help here about doing a dynamic instantiation in C#. What I want to accomplish is to be able to use a string variable that is used as the name in the instantiation. I think you can use reflection or something, but I am lost on this one. Here is my test code snippet and hopefully someone has an answer.

Averages is tied to a class that handles everything. So lets say I wanted to make test the variable and everything that is tied to the string of test could be passed as the instantiation. How could I create an object that can handle the variable test coming in, compile and be used in runtime? I know this may sound out of the ordinary, but instead of me using many IF's with multiple declarations of doubles. I could use a dynamic instantiation. Anyone that can help out I would be most appreciative.

Averages test = new Averages();
 double[] testresult;
 testresult = test.sma();

womp,,,I want to dynamically declare arrays of doubles. I already know how to declare a static array. What I am trying to accomplish is eliminating declaring 30 arrays that bascially do the same thing over and over again with a different naming.

So instead of doing this:

                if (UITAName == "SMA")
                {
                    Averages sma = new Averages();
                    double[] smaresult;
                    smaresult = sma.sma(UITAName, YVal, UITPeriod, UITShift);
                    chart1.Series[UITA].Points.DataBindXY(test2, test1);

                }
                if (UITAName == "TMA")
                {
                    Averages tma = new Averages();
                    double[] tmaresult;
                    tmaresult = tma.tma(UITAName, YVal, UITPeriod);
                    chart1.Series[UITA].Points.DataBindXY(XVal, tmaresult);
                }

                else
                    if (UITAName == "EMA")
                    {
                        Averages ema = new Averages();
                        double[] emaresult;
                        emaresult = ema.ema(UITAName, YVal, UITPeriod);
                        chart1.Series[UITA].Points.DataBindXY(XVal, emaresult);
                    }

I want to do this only once for everything instead of doing IF statements. The problem is that you cannot compile with a declaration of a string. There has to be a way I just do not know how.

Averages UITAName = new Averages(); double[] UITANameresult; UITANameresult = UITAName.UITAName(UITAName, YVal, UITPeriod); chart1.Series[UITA].Points.DataBindXY(XVal, UITANameresult);

+3  A: 

You can instantiate a class dynamically using Reflection, with Activator.CreateInstance.

Activator.CreateInstance("MyAssembly", "MyType");

However I'm not entirely clear on what you're trying to do. If you already have a class called Averages, what do you need dynamically instantiated? And I'm a bit worried by what you mean that it's "tied to a class that handles everything"...

womp
hmmm...let me reflect on that. +1
kenny
I want to dynamically instantiate the array of doubles. Lets say I have test as the declaration of the double. Now I have a database that has different values that I can pass to the variable "test". I want to dynamically instantiate test of doubles with any variable coming in. Is this possible? Thanks for the prompt reply.
MB
Wow, I think that comment made it even *less* clear.
Aaronaught
Ok let me try this again. I have declared an array of double such as sma = test;string test;Averages test = new Averages(); double[] testresult; This is a static declaration. I have a database that has values such as "SMA" , "EMA", etc....I want to dynamically instantiate the array of double..So you would use test as the string. How can I get this to dynamically instantiate?
MB
How can you declare "string test" and then "Averages test"? Your explanation is very confusing. Also, if you already know that you're populating an array of doubles, then what do you mean by dynamically instantiate? Just create an array of doubles....?
womp
Okay, how about this - what does your string look like? Are you just trying to change a string into a double? Because you can use the double.Parse() method for this.
womp
+1  A: 

Sounds like you might need to check out Func<> ??? Just my initial assessment without seeing a little more code to give me a clearer context.

To clarify, if you are wanting to pass the values as an argument, like you would on your command line, then you would need to instance the assembly. Otherwise, with Func<T, TResult> you can pass parameters dynamically to a method and get the return value.

Okay...if I get what you are saying...you want something that would resemble:

class Average
{
    public double[] sma()
    {
        // do something
        return dArray;
    }

    public double[] ema()
    {
        // do something
        return dArray;
    }
}

that is...the function 'name' would be the value of the string returned from a database query of some sort?

...and if that is the case then I don't know why you wouldn't just do a dictionary like:

Dictionary<string, double[]> testResults = new Dictionary<string, double[]>();

void GetDoubles(string name, params double[] args)
    {
        testResult[s] = GetAverages(args);
    }
dboarman
Func is great!!
NotDan
A: 

I think reflection might not be the best solution for your situation. Maybe decomposing your code a little bit might help, something along the following lines...

public interface ICalculation
{
    double [] Calculate(double y, double period, double shift);
    double XVal {get;}
}

public class SMA : ICalculation
{
    public override double[] Calculate( double y, double period, double shift )
    {
        // do calculation, setting xval along the way
    }

    // more code
}

public class EMA : ICalculation
{
    public override double[] Calculate( double y, double period, double shift )
    {
        // do calculation,  setting xval along the way
    }

    // more code
}

public class Averages
{
    public void HandleCalculation( ICalculation calc, double y, double p, double s )
    {
        double[] result = calc.Calculate( y, p, s );
        chart.Series[UITA].Points.DataBindXY( calc.XVal, result );
    }
}
BioBuckyBall
+1  A: 

I think this could help you.

If i understand you correctly, you have method initinialization values in db as SMA,EMA,etc and you need to invoke the method at runtime,

   string invokeMethod = GetValueFromDB()  //ur logic to get the SMA or EMA or TMA from db
   Type urType=typeof("yourclassname");
   object unKnownObj = Activator.CreateInstance(urType);

   //Fill your paramters to ur method(SMA,EMA) here
   //ie, sma.sma(UITAName, YVal, UITPeriod, UITShift);           
   object[] paramValue = new object[4];
   paramValue[0] = UITAName;
   paramValue[1] = YVal;
   paramValue[2] = UITPeriod;
   paramValue[3] = UITShift;
   object result=null;


        try
        {
            result = urType.InvokeMember(invokeMethod, System.Reflection.BindingFlags.InvokeMethod, null, unKnownObj, paramValue);


        }
        catch (Exception ex)
        {
            //Ex handler
        }

So this way you can avoid the multiple if loops and will invoke the method directly by the given name..

Cheers

Ramesh Vel

Ramesh Vel