在运行时仅使用称为字符串的类名实例化任何数量的类 [英] Instantiating any number of classes at runtime with only the class name known as a string

查看:50
本文介绍了在运行时仅使用称为字符串的类名实例化任何数量的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个桌面应用程序,该应用程序收集一些数据,然后对数据进行一些后处理.后处理器根据用户选择而有所不同.每个后期处理程序都是一个继承IPostProcessor接口的类,该接口定义了"CrunchNumbers"方法的签名.到目前为止,我有2个后处理器类,但我知道将来还会添加更多类.当前,我有一个"if"-"else if"语句,该语句根据作为字符串传入的类名称选择后处理器.在"else if"内部,它调用适当的工厂,该工厂返回与指定字符串相对应的类实例(请参见下面的代码).问题是我希望能够添加新的后处理器类,而无需更改实例化它们的代码.所以我的问题是,我该如何编写将在运行时实例化一个类的代码(该类继承了一个已知接口),该类将在将来的某个时间才编写?换句话说,我不想继续返回并在下面的代码中添加更多的"else if"行.


I have a desktop application that collects some data and then does some postprocessing to the data. The post processor varies depending on user selection. Each post processer is a class which inherits the IPostProcessor interface which defines the signature of the "CrunchNumbers" method. So far I have 2 post processor classes but I know that more will be added in the future. Currently I have an "if"-"else if" statement that selects the postprocessor based on the class name passed in as a string. Inside the "else if" it calls the appropriate factory which returns the class instance corresponding to the string specified (see code below). The problem is that I want to be able to add new post processor classes without altering the code that instantiates them. So my question is, how can I write code that will intantitate a class at runtime (that inherits a know interface) for a class that won''t be written until some time in the future? In other words, I don''t want to have to keep coming back and adding more "else if" lines to my code below.


IPostProcessor biasScaleFactorPP;
IPostProcessor AllanVariancePP;
private void LaunchPostProcessor(double[,] twoDArray, string postProcessorName)
{
    if (postProcessorName == BiasScaleFactorString && !closing)
    {
        if (biasScaleFactorPP == null)
        {
            biasScaleFactorPP = PostProcFactory.CreatePostProcessor<BiasScaleFactor>();
            biasScaleFactorPP.Initialize(serialNumbers, dataId, populatedLocations);
        }
        bsfDelegate = new DelegateToMethod(biasScaleFactorPP.CrunchNumbers);
        bsfDelegate(twoDArray, PostProcParams);
    }
    else if (postProcessorName == AllanVarianceString && !closing)
    {
        if (AllanVariancePP == null)
        {
            AllanVariancePP = PostProcFactory.CreatePostProcessor<AllanVariance>();
            AllanVariancePP.Initialize(serialNumbers, dataId, populatedLocations);
        }
        avDelegate = new DelegateToMethod(AllanVariancePP.CrunchNumbers);
        avDelegate(twoDArray, PostProcParams);
    }
    else if (!closing)
    {
        throw new Exception(string.Concat(postProcessorName, " is not recognized as a valid post processor"));
    }
}

推荐答案

这是非常糟糕的方法.

而是定义一些接口,引用其程序集使其可见.使用Reflection并找出支持该接口的类.使用从Type获得的System.Reflection.ConstructorInfo实例化.

获取基于类型的类型名称是不好的,因为它基于硬编码"字符串.当有人决定重命名一个类时,该应用程序会编译并运行,但由于找不到该类型而突然崩溃.有人只在一个地方或一个程序集中重命名了一个接口,编译器显示了一个错误,可以立即修复.

—SA
This is extremely bad method.

Instead, define some interface, reference its assembly to make it visible. Use Reflection and find out your classes which support this interface. Instantiate using System.Reflection.ConstructorInfo obtained from Type.

Getting the Type based type name is bad because it is based on "hard-coded" string. When somebody decides to rename a class, the application compiles and runs but crashes because the type is not found, all of a sudden. It somebody renames an interface in just one place or one assembly, compiler shows an error which can be fixed immediately.

—SA


这篇关于在运行时仅使用称为字符串的类名实例化任何数量的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆