6

我有一个调用接口IStep,可以进行一些计算(参见“名词王国中的执行”)。在运行时,我想按类名选择适当的实现。

// 像这样使用:
IStep step = GetStep(sName);
4

4 回答 4

8

你的问题很混乱...

如果要查找实现 IStep 的类型,请执行以下操作:

foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
{
  if (!typeof(IStep).IsAssignableFrom(t)) continue;
  Console.WriteLine(t.FullName + " implements " + typeof(IStep).FullName);
}

如果您已经知道所需类型的名称,请执行此操作

IStep step = (IStep)Activator.CreateInstance(Type.GetType("MyNamespace.MyType"));
于 2008-08-21T11:53:00.647 回答
2

如果实现具有无参数构造函数,则可以使用 System.Activator 类来执行此操作。除了类名之外,您还需要指定程序集名称:

IStep step = System.Activator.CreateInstance(sAssemblyName, sClassName).Unwrap() as IStep;

http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

于 2008-08-21T11:50:56.050 回答
1

根据其他人指出的内容,这就是我最终写的内容:

///
/// 这里发生了一些神奇的事情:通过反射类型找到要采取的正确操作
/// 从具有该名称的 IStep 子类化。
///
私人 IStep GetStep(字符串 sName)
{
    程序集程序集 = Assembly.GetAssembly(typeof (IStep));

    尝试
    {
        return (IStep) (来自 t in assembly.GetTypes()
                        其中 t.Name == sName && t.GetInterface("IStep") != null
                        选择
                        ).First().GetConstructor(新类型[] {}
                        ).Invoke(新对象[] {});
    }
    捕获(InvalidOperationException e)
    {
        throw new ArgumentException("不支持动作:" + sName, e);
    }
}
于 2008-08-21T11:54:53.933 回答
0

好吧,Assembly.CreateInstance 似乎是要走的路——唯一的问题是它需要类型的完全限定名称,即包括命名空间。

于 2008-08-21T11:56:42.743 回答