C#动态实例化

时间:2010-02-06 04:49:15

标签: c# reflection

我需要一些关于在C#中进行动态实例化的帮助。我想要完成的是能够使用在实例化中用作名称的字符串变量。我认为你可以使用反射或其他东西,但我迷失了这个。这是我的测试代码片段,希望有人有答案。

平均值与处理所有内容的类相关联。因此,我想说我想对变量进行测试,并且与测试字符串相关的所有内容都可以作为实例化传递。我怎样才能创建一个可以处理变量测试的对象,编译并在运行时使用?我知道这可能听起来与众不同,但我并没有使用许多带有双重声明的IF。我可以使用动态实例化。任何可以提供帮助的人都会非常感激。

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

womp ,,,我想动态声明双打数组。我已经知道如何声明一个静态数组。我想要完成的是消除声明30个阵列,这些阵列基本上使用不同的命名一遍又一遍地做同样的事情。

所以不要这样做:

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

我想对所有事情只做一次,而不是做IF语句。问题是您无法使用字符串声明进行编译。必须有一种方法我不知道如何。

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

4 个答案:

答案 0 :(得分:4)

您可以使用Reflection Activator.CreateInstance动态实例化一个类。

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

然而,我并不完全清楚你要做什么。如果您已经有一个名为Averages的类,那么您需要动态实例化什么?而且我有点担心你的意思是“它与一个处理一切的课程联系在一起”......

答案 1 :(得分:2)

听起来你可能需要查看Func<> ???只是我最初的评估,没有看到更多的代码,以给我一个更清晰的背景。

为了澄清,如果您希望将值作为参数传递,就像在命令行中那样,那么您需要对程序集进行实例化。否则,使用Func<T, TResult>,您可以将参数动态传递给方法并获取返回值。

好的......如果我得到你说的话......你想要的东西类似于:

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

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

是......函数'name'是从某种数据库查询返回的字符串的值?

...如果是这种情况,那么我不知道为什么你不会只做一个字典:

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

void GetDoubles(string name, params double[] args)
    {
        testResult[s] = GetAverages(args);
    }

答案 2 :(得分:2)

我认为这可以帮到你。

如果我理解正确,你在db中有方法初始化值为SMA,EMA等,你需要在运行时调用该方法,

   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
        }

所以这样你就可以避免多个if循环,并且会直接通过给定的名称来调用方法。

答案 3 :(得分:0)

我认为反思可能不是最适合您情况的解决方案。也许稍微分解你的代码可能会有所帮助,这可能是以下几点......

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