HOW TO get an overloaded private/protected method using reflection - c#

using System;
using System.Reflection;
namespace Reflection
{
class Test
{
protected void methodname(int i)
{
Console.WriteLine(("in the world of the reflection- only i"));
Console.Read();
}
protected void methodname(int i, int j)
{
Console.WriteLine(("in the world of the reflection i , j"));
Console.Read();
}
}
class Program
{
static void Main(string[] args)
{
// BindingFlags eFlags = BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public|BindingFlags.NonPublic;
BindingFlags eFlags = BindingFlags.Instance|BindingFlags.NonPublic;
Test aTest = new Test();
MethodInfo mInfoMethod = typeof(Reflection.Test).GetMethod("methodname", eFlags);
mInfoMethod.Invoke(aTest, new object[] { 10 ,20});
}
}
}
I want to call both Getmethod() overloaded methods. If i give the method name , an runtime error is thrown(ambigous method call) . How to avoid this and how each method can be called.

You have to pass types of your overloaded method, this is how reflection sorts out your desired method when there's a overload.
You can't call both the methods as it has different types of input parameter. You have to know exactly which one you exactly want to call, and pass along a Type[], for instance:
// invoking overload with two parameters
MethodInfo mInfoMethod =
typeof(Reflection.Test).GetMethod(
"methodname",
BindingFlags.Instance | BindingFlags.NonPublic,
Type.DefaultBinder,
new[] {typeof (int), typeof (int)},
null);
mInfoMethod.Invoke(aTest, new object[] { 10 ,20});
OR
// invoking overload with one parameters
MethodInfo mInfoMethod =
typeof(Reflection.Test).GetMethod(
"methodname",
vBindingFlags.Instance | BindingFlags.NonPublic,
Type.DefaultBinder,
new[] { typeof (int) },
null);
mInfoMethod.Invoke(aTest, new object[] { 10 });

Use 'GetMethods' instead to retrieve all the overloads, then pick the ones you want.

Please find a working sample below:
public class ReflectionSample
{
protected void Method(int i)
{
Console.WriteLine(string.Format("in the world of the reflection- only {0}", i));
Console.Read();
}
protected void Method(int i, int j)
{
Console.WriteLine(string.Format("in the world of the reflection {0} , {1}", i,j));
Console.Read();
}
}
class Program
{
static void Main(string[] args)
{
var eFlags = BindingFlags.Instance | BindingFlags.NonPublic;
var objType = Type.GetType("Sample.ReflectionSample");
var methods = objType.GetMethods(eFlags);
foreach (var method in methods)
{
if (method.Name == "Method")
{
Console.WriteLine("Method name is :" + method.Name);
var parameters = method.GetParameters();
int value = 10;
List<object> param = new List<object>();
for (int i = 0; i < parameters.Count(); i++)
{
param.Add(value * 5);
}
Console.WriteLine(parameters.Count());
method.Invoke(new ReflectionSample(), param.ToArray());
}
}
}
}

can u try like this
You have to specify which method you want:
class SomeType
{
void Foo(int size, string bar) { }
void Foo() { }
}
SomeType obj = new SomeType();
// call with int and string arguments
obj.GetType().GetMethod("Foo", new Type[] { typeof(int), typeof(string)).Invoke(obj, new object[] { 42, "Hello" });
// call without arguments
obj.GetType().GetMethod("Foo", new Type[0]).Invoke(obj, new object[0]);

Related

Pass static method stored in string in c#

How can I pass the static method with params which are stored in a string? I want to use method from another class with params. I have a dictionary depending on what folder which function should be used.
Here is main class:
foreach (string folder in folders)
{
foreach (string file in Directory.EnumerateFiles(folder))
{
//switch (folder)
//{
//}
foreach(var a in GetDictionaryToFunction())
{
string nameFolder = folder.Split('\\')[folder.Split('\\').Count() - 1];
if (a.Key == nameFolder)
{
//And here I want to use the specified method with file path as param.
Type thisType = this.GetType();
MethodInfo theMethod = thisType.GetMethod(a.Value);// +"("+ file + ")");
theMethod.Invoke(theMethod, null);
}
}
}
And I'm trying to use function from this class:
class File
{
public static void ReadPayments(string filePath)
{
string[] rows = Reader.ReadCsv(filePath);
if (rows.Count() == 0) return;
listPlatnosci.Clear();
string fileName = Path.GetFileName(filePath);
foreach (string row in rows)
{
TransformRow(row, fileName);
}
}
example dictionary: <folder, FunctionToAddValues>
ReadPayments should be define as follow:
public class ClassWithTheMethod
{
public static void ReadPayments(string folder)
{
//Whatever
}
}
And call it by using this:
MethodInfo theMethod = typeof(ClassWithTheMethod).GetMethod(a.Value, BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string) }, null);
theMethod.Invoke(null, new object[] { a.Key }); //null for static methods
Here is code which worked for me:
MethodInfo theMethod = typeof(File).GetMethod(a.Value, BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string) }, null);
theMethod.Invoke(null, new object[] { file });

How to use reflection to get a method with a ref keyword?

Yeah so I set up a little TestClass to figure out what GetMethod would work to actually find the method Test(ref int i). But so far nothing worked.
[Button(nameof(Method))]
public bool whatever;
private void Test(ref int i)
{
Debug.Log("Works");
}
private void Method()
{
Type[] types = { typeof(int) };
MethodInfo methodInfo = GetType().GetMethod(nameof(Test),
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
null, types, null);
Debug.Log(methodInfo);
}
What am I supposed to do? I couldn't find anything on the web so far (for GetMethod specifically)
If you mix Eser + gcores you obtain:
private void Test(ref int i)
{
Console.WriteLine(i);
i++;
}
private void Test2(out int i)
{
i = 1000;
}
public void Method()
{
Type[] types = { typeof(int).MakeByRefType() };
MethodInfo methodInfo = GetType().GetMethod(nameof(Test), BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
int num = 10;
var pars = new object[] { num };
methodInfo.Invoke(this, pars);
Console.WriteLine(pars[0]);
MethodInfo methodInfo2 = GetType().GetMethod(nameof(Test2), BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
var pars2 = new object[1];
methodInfo2.Invoke(this, pars2);
Console.WriteLine(pars2[0]);
}
Note the typeof(int).MakeByRefType(), and the fact that the object[] array containing the parameters is modified by the invoked method. I've added a second example with out that shows that you still use .MakeByRefType(), only you don't need to initialize the object[] array with a parameter. Ah and you should use the exact BindingFlags you need, not throw every BindingFlags contained in MSDN together. Static and non-static work differently :-)
You can find the method with specified arguments' types by calling an appropriate overload of GetMethod. To make the parameter a reference type use the code:
Type[] types = { typeof(int).MakeByRefType() };

Invoke method in new thread (method name from string)?

Im trying to invoke a method on a new thread in a winforms c# app. But I need the method name to come from a string.
Is it possible to do something like:
public void newThread(string MethodName)
{
new Thread(new ThreadStart(MethodName)).Start();
}
I've tried but cant seem to get this to work?
Any advice would be much appreciated.
One way of doing it can be:
public void NewThread(string MethodName, params object[] parameters)
{
var mi = this.GetType().GetMethod(MethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
Task.Factory.StartNew(() => mi.Invoke(this, parameters), TaskCreationOptions.LongRunning);
}
void Print(int i, string s)
{
Console.WriteLine(i + " " + s);
}
void Dummy()
{
Console.WriteLine("Dummy Method");
}
NewThread("Print", 1, "test");
NewThread("Dummy");
I am assuming you want to call method from within class itself.
Type classType = this.GetType();
object obj = Activator.CreateInstance(classType)
object[] parameters = new object[] { _objval };
MethodInfo mi = classType.GetMethod("MyMethod");
ThreadStart threadMain = delegate () { mi.Invoke(this, parameters); };
new System.Threading.Thread(threadMain).Start();
If not replace this with class you need.

How to pass an argument when invoking a method (reflection)?

I need to call a method, passing an int. using the following code I can fetch the method but not passing the argument. How to fix it?
dynamic obj;
obj = Activator.CreateInstance(Type.GetType(String.Format("{0}.{1}", namespaceName, className)));
var method = this.obj.GetType().GetMethod(this.methodName, new Type[] { typeof(int) });
bool isValidated = method.Invoke(this.obj, new object[1]);
public void myMethod(int id)
{
}
The new object[1] part is how you're specifying the arguments - but you're just passing in an array with a single null reference. You want:
int id = ...; // Whatever you want the value to be
object[] args = new object[] { id };
method.Invoke(obj, args);
(See the MethodBase.Invoke documentation for more details.)
Note that method.Invoke returns object, not bool, so your current code wouldn't even compile. You could cast the return value to bool, but in your example that wouldn't help at execution time as myMethod returns void.
Just pass an object with the invoke method
namespace test
{
public class A
{
public int n { get; set; }
public void NumbMethod(int Number)
{
int n = Number;
console.writeline(n);
}
}
}
class MyClass
{
public static int Main()
{
test mytest = new test();
Type myTypeObj = mytest.GetType();
MethodInfo myMethodInfo = myTypeObj.GetMethod("NumbMethod");
object[] parmint = new object[] {5};
myMethodInfo.Invoke(myClassObj, parmint);
}
}

Reflection to invoke the constructor with ConstructorInfo

In a very Simple class like below,
class Program
{
public Program(int a, int b, int c)
{
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
}
}
and I use reflection to invoke the constructor
something like this...
var constructorInfo = typeof(Program).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) });
object[] lobject = new object[] { };
int one = 1;
int two = 2;
int three = 3;
lobject[0] = one;
lobject[1] = two;
lobject[2] = three;
if (constructorInfo != null)
{
constructorInfo.Invoke(constructorInfo, lobject.ToArray);
}
But I am getting an error saying "object does not match target type constructor info".
any help/comments greatly appreciated.
thanks in advance.
You don't need to pass constructorInfo as a parameter, as soon as you are calling a constructor, but not an instance method of an object.
var constructorInfo = typeof(Program).GetConstructor(
new[] { typeof(int), typeof(int), typeof(int) });
if (constructorInfo != null)
{
object[] lobject = new object[] { 1, 2, 3 };
constructorInfo.Invoke(lobject);
}
For KeyValuePair<T,U>:
public Program(KeyValuePair<int, string> p)
{
Console.WriteLine(string.Format("{0}:\t{1}", p.Key, p.Value));
}
static void Main(string[] args)
{
var constructorInfo = typeof(Program).GetConstructor(
new[] { typeof(KeyValuePair<int, string>) });
if (constructorInfo != null)
{
constructorInfo.Invoke(
new object[] {
new KeyValuePair<int, string>(1, "value for key 1") });
}
Console.ReadLine();
}

Categories