如何在当前程序集中找到具有特定名称的C#接口的实现?

时间:2020-03-05 18:41:27  来源:igfitidea点击:

我有一个名为" IStep"的接口,可以执行一些计算(请参阅"在名词王国中执行")。在运行时,我想通过类名称选择适当的实现。

// use like this:
IStep step = GetStep(sName);

解决方案

回答

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

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

http://msdn.microsoft.com/zh-CN/library/system.activator.createinstance.aspx

回答

问题非常令人困惑...

如果要查找实现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"));

回答

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

/// 
/// Some magic happens here: Find the correct action to take, by reflecting on types 
/// subclassed from IStep with that name.
/// 
private IStep GetStep(string sName)
{
    Assembly assembly = Assembly.GetAssembly(typeof (IStep));

    try
    {
        return (IStep) (from t in assembly.GetTypes()
                        where t.Name == sName && t.GetInterface("IStep") != null
                        select t
                        ).First().GetConstructor(new Type[] {}
                        ).Invoke(new object[] {});
    }
    catch (InvalidOperationException e)
    {
        throw new ArgumentException("Action not supported: " + sName, e);
    }
}

回答

好吧Assembly.CreateInstance似乎是解决这个问题的唯一方法,因为它需要类型的完全限定名称,即包括名称空间。