C# 使用反射调用接口方法

C# 使用反射调用接口方法,c#,reflection,C#,Reflection,我正在使用反射来调用接口方法,并且出现了错误消息“对象引用未设置为对象的实例”。我也尝试使用ConstructorInfo,但也出现了错误。请帮忙 public class ClassA { private void MethodA(int num, ClassC result) { } } public interface InterfaceB { ClassC MethodB(int num); } internal cla

我正在使用反射来调用接口方法,并且出现了错误消息“对象引用未设置为对象的实例”。我也尝试使用ConstructorInfo,但也出现了错误。请帮忙

public class ClassA 
{ 
       private void MethodA(int num, ClassC result)
       {
       } 
}
public interface InterfaceB 
{ 
       ClassC MethodB(int num); 
}
internal class ClassB 
{ 
      public ClassC MethodB(int num)
      {
      } 
}

Type typClassA = Type.GetType("ClassA");
Type typInterfaceB = Type.GetType("InterfaceB");
MethodInfo methodB = typInterfaceB.GetMethod("MethodB", BindingFlags.Public | BindingFlags.Instance); // Error lies here
ClassC result = (ClassC) methodB.Invoke(typInterfaceB, new object[]{num});

MethodInfo methodA = typClassA.GetMethod("MethodA", BindingFlags.NonPublic | BindingFlags.Instance);
methodA.Invoke(typClassA, new object[]{num, result});

ClassB的实际代码没有声明为“publicClassB:InterfaceB”,而是包含更多的类,ClassB是内部访问。请参见编辑的代码。抱歉多次更改代码,因为我不知道如何简化此场景。

我不太明白您想要什么,但我认为您需要这样的东西

public interface InterfaceB 
{
    int method(int d);
}
public class ClassB:InterfaceB
{
    int a = 10;
    public int method(int d)
    {
        return a + d;
    }
}


var b = new ClassB();
var mi = typeof(ClassB).GetInterface("InterfaceB").GetMethod("method");
var res = mi.Invoke(b, new object[] { 10 }); // res == 20
更新
另一种变体

public interface InterfaceB 
{
    int method(int d);
}
public class ClassB:InterfaceB
{
    int a = 10;
    public int method(int d)
    {
        return a + d;
    }
}


var b = new ClassB();
var mi = typeof(InterfaceB).GetMethod("method");
var res = mi.Invoke(b, new object[] { 10 }); // res == 20

您必须为类指定完全限定的名称。请注意下面的例子

namespace ConsoleApplication10
{
    interface IA
    {
        void Print();
    }

    class A : IA
    {
        public void Print()
        {
            Console.WriteLine("Hello");
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Type type = Type.GetType("ConsoleApplication10.A");
            type.GetMethod("Print").Invoke(Activator.CreateInstance(type, null), null);
        }
    }
}

您试图在类型为
System.type
的对象上调用方法,而不是在实现该接口的对象上调用方法

MethodInfo.Invoke
的第一个参数是要在其上调用方法的对象的实例。。。您使用的是
系统的实例。键入
对象,而不是
ClassA
ClassB
所有方法都是实例(非静态)方法,因此您必须创建实例来调用它们,并将这些实例传递给
调用
,例如:

  // Let's call MethodA from ClassA

  Object instanceA = new ClassA();
  MethodInfo methodA = instanceA.GetType().GetMethod("MethodA", BindingFlags.NonPublic | BindingFlags.Instance);

  // Pay attention to 1st argument - instanceA
  methodA.Invoke(instanceA, new object[]{num, result});  

  ...

  // Since ClassB doesn't implement InterfaceB, the only option 
  // is to call MethodB of ClassB
  Object instanceB = new ClassB();
  MethodInfo methodB = instanceB.GetType().GetMethod("MethodB", BindingFlags.Public | BindingFlags.Instance);

  ClassC result = (ClassC) (methodB.Invoke(instanceB, new object[]{num}));
C#不使用。 因此,为了实际实现接口方法,您必须声明类实现该接口:

public class ClassB : InterfaceB
代码中还有其他问题:

Type typInterfaceB = Type.GetType("InterfaceB"); // unless you have no namespace at all, you need to specify the fully qualified name

// Probably you got an NRE because of above issue here
MethodInfo methodB = typInterfaceB.GetMethod("MethodB", BindingFlags.Public | BindingFlags.Instance); 

// this does not work, because the first argument needs to be an instance 
// try "new ClassB()" instead
ClassC result = (ClassC) methodB.Invoke(typInterfaceB, new object[]{num});

如果您确定您的对象具有所需的方法,那么您可以使用和编写如下内容:

var result = (yourObject as dynamic).YourMethod("SomeParam");

您使用的编程语言是什么?为什么要尝试get
Static
方法?你能提供更多的代码吗?C#,实际上我使用的是实例。对不起,我没有把它改回去。一点也不清楚。您是否有实现InterfaceB.MethodB的类的实例?是否可以发布一些实际编译的代码?我很难理解你的意图,这意味着我无法真正尝试回答这个问题。首先,您可以将“class”声明添加到类中,并填写所有方法的返回类型……实际代码不是公共类ClassB:InterfaceB。这非常复杂。为代码提供额外的解释会很有用,这样开发人员就可以理解您的推理。这对于可能不熟悉语法的新开发人员尤其重要。此外,这有助于减少后续问题的需要。你介意用更多的细节更新你的评论吗?
interface IGetNames
{
    string GetFirstName();
    string GetMiddleName();
}
public class GetNames : IGetNames
{
    public string GetFirstName()
    {
        return "First Name";
    }
    public string GetMiddleName()
    {
        return "Middle Name";
    }
}
 static void Main(string[] args)
{
Type _Interface = Type.GetType("ConsoleApplication2.IGetNames");
Type _Class = Type.GetType("ConsoleApplication2.GetNames");
InterfaceMapping GetInterfaceMap = _Class.GetInterfaceMap(_Interface);
MethodInfo methodInfo =  GetInterfaceMap.TargetMethods[0];
object str =  methodInfo.Invoke(Activator.CreateInstance(GetInterfaceMap.TargetType), null);
}