Invoking an Interface method using reflection - c#

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.

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

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

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

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

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

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

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

Related

Call a method through reflection fails

I try to call a method using reflection but method is not called. Below is my code:
private abstract class A<T>
{
public abstract void DoSomething(string asd, T obj);
}
private class MyClass : A<int>
{
public override void DoSomething(string asd, int obj)
{
Console.WriteLine(obj);
}
}
static void Main(string[] args)
{
Type unboundGenericType = typeof(A<>);
Type boundGenericType = unboundGenericType.MakeGenericType(typeof(int));
MethodInfo doSomethingMethod = boundGenericType.GetMethod("DoSomething");
object instance = Activator.CreateInstance(boundGenericType);
doSomethingMethod.Invoke(instance, new object[] {"Hello", 123});
}
I also tried to call the usual method, but also errors :(.
You retrieve the method on a wrong type. The method DoSomething has been implemented in MyClass and not on the generic type you bound.
If you try the following, you will the result you are looking for:
Type myClass = typeof(MyClass);
MethodInfo doSomethingMethod = myClass.GetMethod("DoSomething");
object instance = Activator.CreateInstance(myClass);
doSomethingMethod.Invoke(instance, new object[] { "Hello", 123 });

How to call Method of Private Property using Reflection in c#?

I have some problems with my project.
I want to call one method from private Property like private clsBUS_DEMO prop_DEMO
clsBUS_DEMO has a Method, which Name is public void SayHello().
This is my code
PropertyInfo p = this.GetType().GetProperty("SayHello");
p is null because program can't find prop_DEMO
Can anybody help me about this?
clsBUS_DEMO prop_DEMO is not a property, it's a Field. You need to use GetFields to get it and also since it's private you need to pass BindingFlags.NonPublic and BindingFlags.Instance.
Here is a sample of how you should do it
static void Main(string[] args)
{
Bar bar = new Bar();
Foo foo = (Foo)bar.GetType().GetField("a", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(bar);
foo.GetType().GetMethod("ShowMessage").Invoke(foo,new object[] { });
}
public class Bar
{
private Foo a;
public Bar()
{
a = new Foo();
}
}
public class Foo
{
public void ShowMessage()
{
Console.WriteLine("Hello World!");
}
}
Okay guys!
I'm done :)
I just Create Property get{} set{} and use this code :D
PropertyInfo p = this.GetType().GetProperty("LoaiSP_BUS", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
Thanks all!
Call a method of private property? Not sure if I understood what you want, it would be useful to have the class that represent you object. Do you mean call a property that returns an object and then call a method of that object?
Anyways, I think there's a lot information out there about that topic, for example:
How do I use reflection to invoke a private method?
Find a private field with Reflection?
class MyClass1
{
public MyClass1()
{
Prop = new MyClass2();
}
public MyClass2 Prop { get; set; }
}
class MyClass2
{
private int Test()
{
return 5;
}
}
static void Main(string[] args)
{
var obj = new MyClass1();
var obj2 = obj.Prop;
var propInfo = obj.GetType().GetProperty("Prop");
var obj2Reflection = propInfo.GetValue(obj, null);
var dynMethod = obj2.GetType().GetMethod("Test", BindingFlags.NonPublic | BindingFlags.Instance);
var obj2Return = dynMethod.Invoke(obj2, null);
}

Dynamic adapter creation for static class from interface

Problem: I want to write test for an application that has many static classes with static methods, so switching a often used class to dependency injection is impossible in one step.
So I want to preserve the static class, create a adapter class with an interface that calls the static methods, so I can use this interface step by step for dependency injection. (as explained here: https://stackoverflow.com/a/2416447/1453662)
But I don't want to write so many adapter classes for all the static classes so my question is if its possible to write a factory that will create a adapter class for a given interface type and a given target static class type e.g.:
// this is the problem
public static class CalculatorStatic {
public static int ComplexCalculation(int a, int b) {
return a + b;
}
}
// I will write this
public interface ICalculator {
int ComplexCalculation(int a, int b);
}
// I don't want to write this
public class CalculatorAdapter : ICalculator {
public int ComplexCalculation(int a, int b) {
return CalculatorStatic.ComplexCalculation(a, b);
}
}
// This should create all adapters for me
public class AdapterFactory {
public T CreateAdapter<T>(Type staticClassType) { // T is the InterfaceType
// Do some magic and return a dynamically created adapter
// that implements the interface and calls the static class
}
}
Instead of returning an interface I would suggest to return a delegate as an adapter.
public static TFunc CreateAdapter<TFunc>(Type staticClass, string methodName)
{
var method = staticClass.GetMethod(methodName,
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var parameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
var methodParameters = new ParameterExpression[parameterTypes.Length];
for (int i = 0; i < parameterTypes.Length; i++)
{
methodParameters[i] = Expression.Parameter(parameterTypes[i], "p" + i);
}
var lambda = Expression.Lambda<TFunc>(
Expression.Call(null, method, methodParameters), methodParameters);
return lambda.Compile();
}
And use it like this:
var adapter = CreateAdapter<Func<int, int, int>>(typeof(CalculatorStatic),
nameof(CalculatorStatic.ComplexCalculation));
Console.WriteLine(adapter(1, 2));
If you really-really want to use interfaces (because it has more than one method), you should create an adapter factory for each interface:
public ICalculator CreateAdapter(Type staticClassType)
{
return new CalculatorAdapter(staticClassType);
}
// todo: factory methods for other interfaces, too
And the calculator adapter:
private class CalculatorAdapter: ICalculator
{
private readonly Func<int, int, int> complexCalculationAdapter;
internal CalculatorAdapter(Type staticClassType)
{
complexCalculationAdapter = CreateAdapter<Func<int, int, int>>(staticClassType,
nameof(ICalculator.ComplexCalculation));
// TODO: initialize the other fields if there are more interface methods
}
public int ComplexCalculation(int a, int b)
{
return complexCalculationAdapter(a, b);
}
}
Update
If you really want to create a single method for all interfaces, you should generate a dynamic class.
Please note that this example is not perfect. You should cache the dynamic assembly and module instead of always creating a new one, and if you call ref/out arguments, you should assign them back, etc. But maybe the intention is clear. Tip for the code: compile a code which implements an interface directly and disassemble it to see what code to emit in the generator.
public static T CreateAdapter<T>(Type staticClassType)
{
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(typeof(T).Name + "Adapter"),
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule(typeof(T).Name + "Adapter.dll");
// public class TAdapter : T
TypeBuilder tb = mb.DefineType(typeof(T).Name + "Adapter", TypeAttributes.Public | TypeAttributes.Class,
typeof(object), new Type[] { typeof(T) });
// creating methods
foreach (var methodInfo in typeof(T).GetMethods())
{
var parameters = methodInfo.GetParameters();
var parameterTypes = parameters.Select(p => p.ParameterType).ToArray();
var method = tb.DefineMethod(methodInfo.Name,
MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
methodInfo.ReturnType, parameterTypes);
// adding parameters
for (int i = 0; i <parameters.Length; i++)
{
method.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name);
}
// calling the static method from the body and returning its result
var staticMethod = staticClassType.GetMethod(methodInfo.Name, parameterTypes);
var code = method.GetILGenerator();
for (int i = 0; i < parameters.Length; i++)
{
code.Emit(OpCodes.Ldarg_S, i + 1);
}
code.Emit(OpCodes.Call, staticMethod);
code.Emit(OpCodes.Ret);
}
return (T)Activator.CreateInstance(tb.CreateType());
}
}

How to call protected constructor in c#?

How to call protected constructor?
public class Foo{
public Foo(a lot of arguments){}
protected Foo(){}
}
var foo=???
This obviously fails test:
public class FooMock:Foo{}
var foo=new FooMock();
Assert(typeof(Foo), foo.GetType());
Call parameterless protected/private constructor:
Foo foo = (Foo)Activator.CreateInstance(typeof(Foo), true);
Call non-public constructor with parameters:
var foo = (Foo)typeof(Foo)
.GetConstructor(
BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance,
null,
new[] { typeof(double) },
null
)
.Invoke(new object[] { 1.0 });
class Foo
{
private Foo(double x){...}
}
You can only call that from a subclass, basically. Your FooMock class will already be calling the protected constructor, because it's equivalent to:
public class FooMock : Foo
{
public FooMock() : base() // Call the protected base constructor
{
}
}
However, your assertion will fail because the type of object referred to be foo is FooMock, not Foo.
An assertion of the form foo is Foo will pass though.
You can't construct an instance of just Foo by calling the protected constructor directly. The point of it being protected instead of public is to ensure that it's only called by subclasses (or within the text of Foo itself).
It's possible that you could call it with reflection within a full trust context, but I'd urge you not to do so.
The only way to cause a protected constructor to be called is to derive from the class and have the derived class delegate to it or to have a static method create it or some other internal method.
EDIT: What the Skeet said!
You cannot call a protected method - although you can call an internal one (using InternalsVisibleTo attribute). You need to expose it in a different way.
Serj-Tm answered adequately but Activator can do it too:
var foo = (Foo) Activator.CreateInstance(typeof(Foo),
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { 2.0 },
CultureInfo.InvariantCulture);
If you want to avoid repeated reflection cost, you can use expressions.
Here is an example of calling a private constructor with a string value.
private static Func<string, T> CreateInstanceFunc()
{
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
var ctor = typeof(T).GetConstructors(flags).Single(
ctors =>
{
var parameters = ctors.GetParameters();
return parameters.Length == 1 && parameters[0].ParameterType == typeof(string);
});
var value = Expression.Parameter(typeof(string), "value");
var body = Expression.New(ctor, value);
var lambda = Expression.Lambda<Func<string, T>>(body, value);
return lambda.Compile();
}
Save the cost of compiling the function multiple times by storing it in a static field.
private static readonly Lazy<Func<string, T>> CreateInstance = new Lazy<Func<string, T>>(CreateInstanceFunc);
Now you can create the object with
CreateInstance.Value("Hello")
If you need to explicitly call the constructor of you base class in your subclass, you have to use the keyword base
may be this will help:
abstract parent class:
public abstract class Animal
{
private string name;
public Animal(string name)
{
this.Name = name;
}
public Animal() { }
public string Name
{
get { return this.name; }
set { this.name = value; }
}
public virtual void talk()
{
Console.WriteLine("Hi,I am an animal");
}
}
class with protected constructor:
public class Lion : Animal
{
private string yahoo;
protected Lion(string name) : base(name)
{
this.Yahoo = "Yahoo!!!";
}
public string Yahoo
{
get
{
return yahoo;
}
set
{
yahoo = value;
}
}
public Lion() { }
}
class Kiara derived from Lion class :
public class Kiara : Lion
{
public Kiara(string name) : base(name)
{
}
public override void talk()
{
Console.WriteLine("HRRRR I'm a Kiara");
}
public Kiara() { }
}
class Simba derived from Lion class :
public class Simba : Lion
{
public Simba(string name) : base(name)
{
}
public override void talk()
{
Console.WriteLine("HRRRR I'm a {0} and this is my daughter:{1} {2}",
new Simba("Simba").Name,
new Kiara("Kiara").Name,
new Simba("Simba").Yahoo);
}
public Simba() { }
}
implementation in main function:
public static void Main(string[] args)
{
Animal lion = new Simba();
lion.Name = "Simba";
lion.talk();
Animal lion1 = new Kiara();
lion1.Name = "Kiara";
lion1.talk();
}

Cast into new Object, Copy values by Property Name

I have the following:
Class 1 (Text, State, Level)
Class 2 (Text, State, Level, Ident)
Is there a way for me to cast an object of Class 2 into into Class 1, and not having to do the usual cast code (Text = c.Text, State = c.State etc.)? Possibly by identifying the property names of each class and copying the value over?
Why not derive Class 2 from Class 1, or have a common base class?
e.g.
class Class1
{
string Text;
string State;
int Level;
}
class Class2 : Class1
{
int Ident;
// ...
}
A Class 2 instance can now be used everywhere a Class 1 instance is required.
Here is a very simple example without any error checking, it simply uses reflection to iterate over the properties of the source object and set the value of the destination object only if the types match.
class Program
{
static void Main(string[] args)
{
var bar = new Bar();
var foo = new Foo {A = 10, B = "Hello World"};
foo.CopyTo(bar);
Console.WriteLine("{0} - {1}", bar.A, bar.B);
}
}
public static class Extensions
{
public static void CopyTo(this object source, object destination)
{
var sourceType = source.GetType();
var destinationType = destination.GetType();
const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
var properties = sourceType.GetProperties(flags);
foreach (var sourceProperty in properties)
{
var destinationProperty = destinationType.GetProperty(sourceProperty.Name, flags);
if (destinationProperty.PropertyType.Equals(sourceProperty.PropertyType))
{
destinationProperty.SetValue(destination, sourceProperty.GetValue(source, null), null);
}
}
}
}
Maybe the problem is more complicated than the question. If not, have you tried inheritance?
class Class1
{
//Text, State, Level
}
class Class2 : Class1
{
//Indent
}
Since Class2 inherits from class 1, you can pass it around as Class1 no casting needed. This works for example:
Class1 obj = new Class2();

Categories

Resources