我的目标: 我有一个系统,我希望其他人能够添加一个C#脚本,其中包含一个特定的方法,我可以在运行时从另一个类中查找和执行。
我的方法: 我创建了一个带有方法的接口,所以我可以遍历任何使用反射实现接口的类并列出它们,然后在所有这些类之间使用方法名称相同。
我的类具有查找期间找到的所有类的枚举,用户可以在运行时在它们之间进行选择。
我现在需要能够获取所选类类型的方法并调用它的方法,问题是我知道方法的名称,但类的类型存储为变量。
守则:
//来自内存的伪代码:
//Possible solution 1:
Type selectedType = typeSelectedByEnum;
MethodInfo genericMethod = selectedType.GetMethod("TheInterfaceMethod").MakeGenericMethod(selectedType);
genericMethod.Invoke(selectedType, new object[0]);
//Possible solution 2: (however I would much prefer to use something avaliable prior to .NET 4.6)
Type selectedType = typeSelectedByEnum;
dynamic changedObj = Convert.ChangeType(selectedType, selectedType);//-Something here needs to implement IConvertable, how would I set this up?
changedObj.TheInterfaceMethod();
//Possible solution 3:
//Your solution??!
任何帮助表示感谢,此时我已经尝试了很多东西,并且对任何可能的运行时替代方案持开放态度。如有必要,我可以提供更多代码。
答案 0 :(得分:4)
由于您使用的是接口来标记具有您的方法" TheInterfaceMethod"的类,因此该方法不能是静态的。这意味着您需要一个对象的实例来调用该方法。 Activator类提供了一种创建对象实例的简单方法,但它确实需要一个具有可见性的默认构造函数(在您的情况下很可能是公共构造函数)。
我也注意到你的例子的潜在问题是你正在调用" MakeGenericMethod"。仅当函数具有一些您需要定义的具有有意义函数的泛型类型参数时,才需要这样做。比如这个界面:
interface IInterfaceWithGenericMethod
{
void TheInterfaceMethod<T>();
}
以下是使用变量的示例:
Type selectedType = typeSelectedByEnum;
MethodInfo method = selectedType.GetMethod("TheInterfaceMethod");
object obj = Activator.CreateInstance(selectedType);
method.Invoke(obj, null);
有趣的是,一旦你有了一个对象的实例,你就不再需要反射来调用该方法了。您只需将其强制转换为界面即可。我们假设您的界面名为IAwesomeInterface:
Type selectedType = typeSelectedByEnum;
object obj = Activator.CreateInstance(selectedType);
IAwesomeInterface converted = obj as IAwesomeInterface;
converted.TheInterfaceMethod();