使用反射调用Interface方法

时间:2013-12-30 11:26:13

标签: c# reflection

我正在使用反射来调用Interface方法,并且我有此错误消息“对象引用未设置为对象的实例”。我也尝试使用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的实际代码未声明为“public ClassB:InterfaceB”,但包含更多类,ClassB是内部访问。查看编辑的代码。我不知道如何简化这种情况,多次更改代码的道歉。

7 个答案:

答案 0 :(得分:2)

您必须为课程提供完全限定的名称。请注意以下示例

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

MethodInfo.Invoke的第一个参数是您要调用方法的对象的实例...您正在使用System.Type对象的实例,而不是ClassA中的一个实例}或ClassB

答案 3 :(得分:0)

您的所有方法都是实例(不是静态)方法,因此必须创建实例来调用它们,并传递这些实例Invoke,例如:

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

答案 4 :(得分:0)

C#使用duck-typing。 因此,为了实际实现接口方法,您必须声明您的类实现该接口:

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

答案 5 :(得分:0)

如果您确定您的对象需要方法,那么您可以使用dynamic并像这样写:

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

答案 6 :(得分:0)

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