-2

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

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

此外,我有 2 个不同的类实现上述接口,Class1并且Class2

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

2 回答 2

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);
于 2013-08-19T01:44:22.080 回答
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找到。

警告:如果您的实现类位于不同的程序集中(我猜是您的情况,请确认),您需要TypeAssembly声明的类型中获取 ,否则您将在此行中获得空值: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是一个限定名

于 2013-08-19T03:17:47.200 回答