如果你只知道字符串中的类名,如何用接口初始化类
本文关键字:何用 初始化 接口 字符串 如果 | 更新日期: 2023-09-27 18:28:03
我有一个名为IClass
的接口,声明方法Calculate
如下:
public interface IClass
{
public int Calculate(int x);
}
此外,我有两个不同的类来实现上述接口,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;
}
}
我认为您可能忽略了继承这一点。您正在使用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);
您可能有兴趣使用Activator
class:
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
是一个限定名称。