Reputation: 19
I am using reflection to invoke an Interface method and I have this error message "Object reference not set to an instance of an object." I try using ConstructorInfo too and also have error. Please help.
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});
The actual code for ClassB is not declared as "public ClassB : InterfaceB" but include more classes and ClassB is internal access. See edited codes. Apology for changing the codes so many times as I don't know how to simplify this scenario.
Upvotes: 1
Views: 10490
Reputation: 1
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);
}
Upvotes: 0
Reputation: 1411
You have to give fully qualified name for class . please observe the below example
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);
}
}
}
Upvotes: 2
Reputation: 7445
If you are sure your object has needed method then you can use dynamic and write like this:
var result = (yourObject as dynamic).YourMethod("SomeParam");
Upvotes: 0
Reputation: 8005
C# does not use duck-typing. Therefore in order to actually implement an interface method, you will have to declare that your class implements that interface:
public class ClassB : InterfaceB
There are other problems in your code:
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});
Upvotes: 1
Reputation: 186668
All your methods are instance (not static) methods, so you have to create instances to call them, and pass these instances to Invoke
, for instance:
// 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}));
Upvotes: 0
Reputation: 28272
You are trying to invoke a method on an object of type System.Type
, and not on the object that implements that interface.
The first parameter of MethodInfo.Invoke
is the instance of the object you want to invoke the method on... you are using an instance of a System.Type
object, and not one of ClassA
or ClassB
Upvotes: 0
Reputation: 13381
i don't quite understand what you want, but i think you need something like this
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
UPDATE
yet another variant
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
Upvotes: 0