如果只知道字符串中的类名,如何使用接口启动类

时间:2013-08-19 01:34:16

标签: c# class interface

我有一个名为IClass的界面,声明方法Calculate,如下所示:

public interface IClass
{
   public int Calculate(int x);
}

此外,我有2个不同的类实现上述接口,Class1Class2

public class Class1: IClass
{
   public int Calculate(int x)
   {
      // do some calc with method 1 here
   }
}

public class Class2: IClass
{
   public int Calculate(int x)
   {
      // do some calc with method 2 here
   }
}

然后我想从主类调用它,但是有限制,我不知道类类型,我只知道类字符串名称(因为它是一个类库 - 其他人可能会为它编写代码)。

问题是:如何通过仅知道其名称来实例化特定类(并调用方法Calculate

public class MainForm()
{
    public int CalcUsing(string classname, int x)
    {
       IClass myclass = new Type(typeof(classname))()   // doesn't work here
       int result = myclass.Calculate(x);
       return result;
    }
}

2 个答案:

答案 0 :(得分:1)

我想你可能在这里错过了继承点。您正在使用IClass接口创建合同。因此,您在MainForm CalcUsing中的方法应该采用IClass类型的参数,因为您(正如您所说)将不知道传入的类的名称。这使得某人能够声明实现您的接口的类并传递它的一个实例。

public int CalcUsing(IClass myClass, int x)
{
     int result = myclass.Calculate(x);
     return result;
}

class SomeClass : IClass
{
     //Implement the Calculate(int) method here
}

//Then the user of your class can do this with an instance of your form due to 
//SomeClass inheriting the IClass type
MainForm.CalcUsing(new SomeClass(), x);

答案 1 :(得分:1)

您可能有兴趣使用 Activator 类:

try 
{
    // Get type
    Type t = Type.GetType(fullyQualifiedNameOfYourImplementingClass);

    // Instantiate
    IClass calculator = (IClass)Activator.CreateInstance(t);

    // Invoke
    calculator.Calculate(x);
}
catch (Exception ex)
{
    // log exception and throw...
    throw ex;
}

动态类型实例化有很多资源,可以在this other SO thread找到。

警告:如果您的实施类位于不同的程序集中(我猜您的情况,请确认),您需要从{{Type获取Assembly 1}}声明了类型,否则你将在这一行得到一个空值:Type t = Type.GetType(className);。 在这个方向上,我们可以像这样重写上面的解决方案:

// Get the assembly containing the implementations. I'm assuming both interface and implementation are in the same assembly
Assembly assembly = typeof(IClass).Assembly;

// Get type. note that know we made use of the aseembly to locate the Type.
Type t = assembly.GetType(className);
    IClass calculator = (IClass)Activator.CreateInstance(t);

确保 className是合格的名称