我有一个名为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;
}
}
答案 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
是合格的名称。