如何仅从接口和方法名称调用方法?
How to invoke method only from interface and method name?
在我的程序中,我们引用了另一个程序集,而那个程序集中肯定有一个实现实例。所以我们想在 运行 时间调用它的方法。我们知道接口和方法名,但是实现实例名还不确定。如何仅从接口和方法名称调用方法?
Type outerInterface = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes()
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Object instance = Activator.CreateInstance(outerInterface);
MethodInfo mi = outerInterface.GetMethod("SampleMethod");
var result = mi.Invoke(instance, new object[]{"you will see me"});
抛出异常:
An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll
Additional information: Cannot create an instance of an interface.
引用的汇编代码在这里:
namespace AnotherAssembly
{
public interface ISample
{
string SampleMethod(string name);
}
public class Sample : ISample
{
public string SampleMethod(string name)
{
return string.Format("{0}--{1}", name, "Alexsanda");
}
}
}
但是反射部分不工作,我不确定如何才能让它工作得很好。
编辑:我不清楚实例名,只知道接口名和方法名。但我知道肯定有一个来自该程序集接口的实现class。
您的错误信息非常清楚:您不能创建接口实例。想象一下,如果您写...
var x = new ISample()
... 在正常代码中。这完全没有意义。
错误源于这些代码行...
Type outerInterface = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes()
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Object instance = Activator.CreateInstance(outerInterface);
... 在上面的清单中,您找到接口 本身 然后尝试实例化它。
您真正想要做的是找到一个实现接口的类型并实例化它...
Type type = Assembly.Load("AnotherAssembly")
.GetTypes()
.Single(t => t.GetInterfaces().Contains(typeof(ISample)));
ISample instance = (ISample) Activator.CreateInstance(type);
string result = instance.SampleMethod("test");
...
请注意我如何 cast 将实例 ISample
- 这消除了调用 GetMethod
.
的需要
如果您还没有对程序集的引用,您可以这样做:
Type[] types = Assembly
.Load("AnotherAssembly")
.GetTypes();
Type sampleInterface = types
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Type type = types
.Single(t => t.GetInterfaces().Contains(sampleInterface));
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("SampleMethod");
string result = (string) method.Invoke(instance, new object[] { "you will see me" });
您无法实例化一个接口,但您可以找到 class 实现它:
Assembly assembly = Assembly.LoadAssembly("AnotherAssemblyFile");
Type[] assemblyTypes = assembly.GetTypes();
Type ISampleType = assemblyTypes.GetType("NameSpace.ISample");
Type sampleType = assemblyTypes.Single(type =>
(type != ISampleType) && ISampleType.IsAssignableFrom(type));
object instance = Activator.CreateInstance(sampleType);
MethodInfo mi = sampleType .GetMethod("SampleMethod");
var result = mi.Invoke(instance, new object[]{"you will see me"});
你不能创建接口类型的实例,因为接口只是一个API,它是一个契约定义,没有别的。实际上,如果你尝试实例化接口,你会得到异常:
System.MissingMethodException: Cannot create an instance of an
interface.
因此您需要获取实现您的接口的类型并实例化该类型的实例:
var anotherAssemblyTypes = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes();
// get interface type
Type outerInterface = anotherAssemblyTypes
.Single(t => t.Name == "ISample" && t.IsInterface);
// find class which implements it
Type outerClass = anotherAssemblyTypes
.Single(t => !t.IsInterface && outerInterface.IsAssignableFrom(t));
// instantiate class
dynamic obj = Activator.CreateInstance(outerClass);
string result = obj.SampleMethod("Bob");
当然你不必在这里使用动态对象。我用它只是为了测试 SampleMethod 被调用。
在我的程序中,我们引用了另一个程序集,而那个程序集中肯定有一个实现实例。所以我们想在 运行 时间调用它的方法。我们知道接口和方法名,但是实现实例名还不确定。如何仅从接口和方法名称调用方法?
Type outerInterface = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes()
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Object instance = Activator.CreateInstance(outerInterface);
MethodInfo mi = outerInterface.GetMethod("SampleMethod");
var result = mi.Invoke(instance, new object[]{"you will see me"});
抛出异常:
An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll
Additional information: Cannot create an instance of an interface.
引用的汇编代码在这里:
namespace AnotherAssembly
{
public interface ISample
{
string SampleMethod(string name);
}
public class Sample : ISample
{
public string SampleMethod(string name)
{
return string.Format("{0}--{1}", name, "Alexsanda");
}
}
}
但是反射部分不工作,我不确定如何才能让它工作得很好。
编辑:我不清楚实例名,只知道接口名和方法名。但我知道肯定有一个来自该程序集接口的实现class。
您的错误信息非常清楚:您不能创建接口实例。想象一下,如果您写...
var x = new ISample()
... 在正常代码中。这完全没有意义。
错误源于这些代码行...
Type outerInterface = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes()
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Object instance = Activator.CreateInstance(outerInterface);
... 在上面的清单中,您找到接口 本身 然后尝试实例化它。
您真正想要做的是找到一个实现接口的类型并实例化它...
Type type = Assembly.Load("AnotherAssembly")
.GetTypes()
.Single(t => t.GetInterfaces().Contains(typeof(ISample)));
ISample instance = (ISample) Activator.CreateInstance(type);
string result = instance.SampleMethod("test");
...
请注意我如何 cast 将实例 ISample
- 这消除了调用 GetMethod
.
如果您还没有对程序集的引用,您可以这样做:
Type[] types = Assembly
.Load("AnotherAssembly")
.GetTypes();
Type sampleInterface = types
.Single(f => f.Name == "ISample" && f.IsInterface == true);
Type type = types
.Single(t => t.GetInterfaces().Contains(sampleInterface));
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("SampleMethod");
string result = (string) method.Invoke(instance, new object[] { "you will see me" });
您无法实例化一个接口,但您可以找到 class 实现它:
Assembly assembly = Assembly.LoadAssembly("AnotherAssemblyFile");
Type[] assemblyTypes = assembly.GetTypes();
Type ISampleType = assemblyTypes.GetType("NameSpace.ISample");
Type sampleType = assemblyTypes.Single(type =>
(type != ISampleType) && ISampleType.IsAssignableFrom(type));
object instance = Activator.CreateInstance(sampleType);
MethodInfo mi = sampleType .GetMethod("SampleMethod");
var result = mi.Invoke(instance, new object[]{"you will see me"});
你不能创建接口类型的实例,因为接口只是一个API,它是一个契约定义,没有别的。实际上,如果你尝试实例化接口,你会得到异常:
System.MissingMethodException: Cannot create an instance of an interface.
因此您需要获取实现您的接口的类型并实例化该类型的实例:
var anotherAssemblyTypes = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes();
// get interface type
Type outerInterface = anotherAssemblyTypes
.Single(t => t.Name == "ISample" && t.IsInterface);
// find class which implements it
Type outerClass = anotherAssemblyTypes
.Single(t => !t.IsInterface && outerInterface.IsAssignableFrom(t));
// instantiate class
dynamic obj = Activator.CreateInstance(outerClass);
string result = obj.SampleMethod("Bob");
当然你不必在这里使用动态对象。我用它只是为了测试 SampleMethod 被调用。