C#动态实例化

3

我需要在C#中进行动态实例化方面的帮助。我想要实现的是能够使用字符串变量作为实例化中的名称。我认为可以使用反射或其他方法,但我在这方面感到有些迷茫。以下是我的测试代码片段,希望有人能够提供答案。

Averages与处理所有内容的类相关联。所以,假设我想要测试该变量,并且将一切都与test的字符串绑定以传递给实例化。如何创建一个对象来处理输入的test变量,编译并在运行时使用?我知道这可能听起来很不寻常,但是与其使用多个IF和多个double声明,我可以使用动态实例化。任何能提供帮助的人,我都非常感激。

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

嗨,我希望能够动态声明双精度数组。我已经知道如何声明静态数组了。我的目标是消除重复声明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);

你的问题不够清晰。你是在问如何根据类型名称字符串创建一个类的实例吗?你所说的“多个IF语句和多个double声明”是什么意思? - bobbymcr
我认为我可能已经能够拼凑出OP的问题了...??? - IAbstract
1
听起来像是工厂方法模式(http://en.wikipedia.org/wiki/Factory_method_pattern)。 - Ron Klein
@Ron:好判断!如果你是对的,我不会感到惊讶。 - IAbstract
Ron,你能给我一个关于工厂方法的例子吗?我已经谷歌搜索过了,但是对我来说还是非常不清楚。 - MB.
4个回答

5
您可以使用反射动态实例化一个类,使用 Activator.CreateInstance 方法。
Activator.CreateInstance("MyAssembly", "MyType");

不过我不太清楚你想做什么。如果你已经有一个名为 Averages 的类,那么你需要动态实例化什么?而且我对你所说的“它与处理一切的类绑定”有点担忧...


2
嗯...让我好好想一想。+1 - kenny
我想动态实例化双精度数组。假设我有一个名为“test”的双精度声明。现在我有一个数据库,其中有不同的值可以传递给变量“test”。我想动态实例化双精度测试,以便使用任何传入的变量。这可能吗?感谢您的快速回复。 - MB.
好的,让我再试一次。我已经声明了一个双精度数组,例如sma = test; string test; Averages test = new Averages(); double[] testresult; 这是一个静态声明。我有一个数据库,其中包含“SMA”、“EMA”等值……我想动态实例化双精度数组。因此,您将使用test作为字符串。如何使其动态实例化? - MB.
你如何声明“字符串测试”,然后是“平均测试”?你的解释很令人困惑。如果你已经知道你要填充一个双精度数组,那么“动态实例化”是什么意思呢?只需创建一个双精度数组……? - womp
好的,那这样怎么样——你的字符串是什么样子的?你只是想把一个字符串转换成双精度浮点数吗?因为你可以使用 double.Parse() 方法来实现。 - womp

2

我希望这能对你有所帮助。

如果我理解正确,您在数据库中有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循环,并直接通过给定的名称调用方法。

2
听起来你可能需要查看 Func<> ??? 只是我的初步评估,没有看到更多的代码,无法给出更清晰的上下文。
为了澄清,如果您想要像在命令行中一样传递值作为参数,则需要创建程序集实例。否则,使用 Func<T, TResult> 您可以将参数动态传递给方法并获取返回值。
好的...如果我理解你的意思...你想要类似于:
class Average
{
    public double[] sma()
    {
        // do something
        return dArray;
    }

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

这是关于IT技术的内容,需要翻译。如果函数“name”是从某种数据库查询返回的字符串值,那么它就是这个函数的功能吗?

如果是这样的话,我不知道为什么你不直接使用字典,例如:

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接