C# 如何仅从接口和方法名称调用方法?

C# 如何仅从接口和方法名称调用方法?,c#,reflection,C#,Reflection,在我的程序中,我们引用了另一个程序集,并且该程序集中有一个实现实例。因此,我们希望在运行时调用它的方法。我们已经知道了接口和方法名,但是实现实例名并不确定。如何仅从接口和方法名称调用方法 Type outerInterface = Assembly.LoadAssembly("AnotherAssemblyFile").GetTypes() .Single(f => f.Name == "ISample" && f.IsInterface == true); Ob

在我的程序中,我们引用了另一个程序集,并且该程序集中有一个实现实例。因此,我们希望在运行时调用它的方法。我们已经知道了接口和方法名,但是实现实例名并不确定。如何仅从接口和方法名称调用方法

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");
        }
    }
}
但是反射部分不起作用,我不知道如何才能使它工作良好


编辑:我不清楚实例名,只知道接口名和方法名。但是我知道该程序集中的接口中肯定有一个实现类。

您的错误消息非常清楚:您无法创建接口的实例。想象一下如果你写

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");
。。。 注意我如何将实例转换为
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" });

您的错误消息非常清楚:您无法创建接口的实例。想象一下如果你写

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");
。。。 注意我如何将实例转换为
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" });

无法实例化接口,但可以找到实现接口的类:

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"});

无法实例化接口,但可以找到实现接口的类:

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:无法创建 接口

因此,您需要获取实现接口的类型,并实例化该类型的实例:

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是否被调用。

您不能创建接口类型的实例,因为接口只是一个API,它是一个契约定义,其他什么都没有。实际上,如果您尝试实例化接口,您将得到异常:

System.MissingMethodException:无法创建 接口

因此,您需要获取实现接口的类型,并实例化该类型的实例:

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是否被调用。

请提供异常详细信息您无法创建接口实例。您应该创建实现接口的类的实例。例如,在您的案例中,
Sample
Activator.CreateInstance(outerInterface)?您正在尝试创建接口的实例?您应该寻找它的实现。请提供异常详细信息您无法创建接口的实例。您应该创建实现接口的类的实例。例如,在您的案例中,
Sample
Activator.CreateInstance(outerInterface)?您正在尝试创建接口的实例?你们应该寻找它的实现。嗨,我没有直接引用另一个程序集,我只是从文件中动态加载它,如何使用ISample类型,接口名只是一个字符串类型。Thanks@BesLey我更新了我的答案。这就是你想要的吗?@BesLey真棒。如果这个答案回答了你的问题,请考虑将它标记为接受。谢谢。嗨,我没有直接引用另一个程序集,我只是从文件中动态加载它,如何使用ISample类型,接口名只是一个字符串类型。Thanks@BesLey我更新了我的答案。这就是你想要的吗?@BesLey真棒。如果这个答案回答了你的问题,请考虑将它标记为接受。谢谢。您好,我使用了您的示例代码,…typeof(ISampleType)…,找不到类型或命名空间名称“ISampleType”(是否缺少using指令或程序集引用?)。这几乎可以完成,但仍需要修复。因为有两种类型匹配它。这样就行了。类型sampleType=anotherAssemblyTypes.Single(类型=>!Type.IsInterface&&outerInterface.IsAssignableFrom(类型))@BesLey另一个匹配类型必须是ISampleType本身:)我已经修复了代码。您好,我使用了您的示例代码,…typeof(ISampleType)…,找不到类型或命名空间名称“ISampleType”(您是否缺少using指令或程序集引用?)。这几乎可以完成,但仍需要修复。因为有两种类型匹配它。这样就行了。类型sampleType=anotherAssemblyTypes.Single(类型=>!Type.IsInterface&&outerInterface.IsAssignableFrom(类型))@BesLey另一个匹配类型必须是ISampleType本身:)我已经修复了代码。“SampleMehod”是一个字符串变量,但在您的最后一行中,您直接使用它,似乎我无法通过使用动态样式来完成它。@BesLey这就是为什么我只为测试编写关于使用动态的说明的确切原因:“我使用它只是为了测试SampleMethod被称为“很棒,我懂了。这是一个很好的解决方案。谢谢,“SampleMehod”是一个字符串变量,但在您的最后一行中,您直接使用它,似乎我不能使用动态样式来完成它。@BesLey,这不是