如果你只知道字符串中的类名,如何用接口初始化类

本文关键字:何用 初始化 接口 字符串 如果 | 更新日期: 2023-09-27 18:28:03

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

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

此外,我有两个不同的类来实现上述接口,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;
    }
}

如果你只知道字符串中的类名,如何用接口初始化类

我认为您可能忽略了继承这一点。您正在使用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);

您可能有兴趣使用Activatorclass:

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

有很多资源用于动态类型实例化,其中一个可以在另一个SO线程中找到。

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