我正在使用反射来调用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是内部访问。查看编辑的代码。我不知道如何简化这种情况,多次更改代码的道歉。
答案 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);
}