I want to call the functions by their name at run time like
string srFunctionName="MyFunction";
So with using this variable i want to call function named as "MyFunction". How can i do that ?
You could use Reflection:
string strFunctionName = "MyFunction";
// get the type containing the method
Type t = Type.GetType("Foo.Bar.SomeTypeContainingYourFunction");
// you will need an instance of the type if the method you are
// trying to invoke is not static. If it is static you could leave that null
object instance = Activator.CreateInstance(t);
// the arguments that your method expects
new object[] arguments = new object[] { 1, "foo", false };
// invoke the method
object result = t.InvokeMember(
strFunctionName,
BindingFlags.InvokeMethod,
null,
instance,
arguments
);
UPDATE:
As requested in the comments section here's a full example with real functions:
using System;
using System.Reflection;
namespace Foo.Bar
{
public class SomeTypeContainingYourFunction
{
public string MyFunction(int foo, string bar, bool baz)
{
return string.Format("foo: {0}, bar: {1}, baz: {2}", foo, bar, baz);
}
}
}
namespace Bazinga
{
class Program
{
static void Main()
{
var strFunctionName = "MyFunction";
var t = Type.GetType("Foo.Bar.SomeTypeContainingYourFunction");
var instance = Activator.CreateInstance(t);
var arguments = new object[] { 1, "foo", false };
var result = t.InvokeMember(
strFunctionName,
BindingFlags.InvokeMethod,
null,
instance,
arguments
);
Console.WriteLine(result);
}
}
}
Here is an example to close the a form
object instance = form;
Type myType = form.GetType();
myType.InvokeMember("Close", BindingFlags.InvokeMethod, null, instance, null);
You can use reflection to create an object of a class and then call a function using that object.
object Instance = Activator.CreateInstance(t); // t is type
MethodInfo mi = t.GetMethod(srFunctionName);
if (mi != null)
mi.Invoke(Instance, args);
else
logError();
Related
How to use reflection to create an instance of the type below while calling a specific constructor? Checked all the overloads of Activator.CreateInstance but don't think there is a match for this.
In the example below, I want x to be doubled after an instance of SomeType is created, namely, I want the constructor taking the ref int version to be called.
Also, how does MS define the 'best match' algorithm for CreatInstance method?
internal sealed class SomeType
{
//consturctor with non-reference parameter
public SomeType(int x)
{
x *= 3;
}
//constructor with reference parameter
public SomeType(ref int x)
{
x *= 2;
}
}
class Program
{
private static void main()
{
var param = new object[] {4}; // constructor parameter
Console.WriteLine("Param Before consturctor called: " + param[0]);
Object instance = Activator.CreateInstance(typeof(SomeType), param);
Console.WriteLine("Param after constuctor called: " + param[0]);
}
}
In order to match the ref int x parameter, you can create an instance using Type.GetConstructor and passing it an System.Int32& as a parameter:
var ctor = typeof(SomeType).GetConstructor(new[] { Type.GetType("System.Int32&") });
var constructorParameters = new object[] { 1 };
SomeType someType = (SomeType)ctor.Invoke(constructorParameters);
Edit:
As #mikez suggested, it is even better to use typeof(int).MakeByRefType() instead of System.Int32&:
var ctor = typeof(SomeType).GetConstructor(new[] { typeof(int).MakeByRefType(); });
var constructorParameters = new object[] { 1 };
SomeType someType = (SomeType)ctor.Invoke(constructorParameters);
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);
}
}
I get an InvalidOperation Exception when calling MethodInfo.Invoke on my Method, its because it has generic Arguments. After hours of searching in Internet I don't know how to solve this problem. Here is the MethodInfo:
object value = null;
if (propertyType.IsClass)
{
Type primaryKeyType = propertyType.GetPrimaryKeyType();
object primaryKeyValue = property.Value.ToValue(primaryKeyType);
MethodInfo GetEntityMethodInfo = typeof(ReportSettingsExtensions)
.GetMethod("GetEntity", BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.NonPublic);
object entity = propertyType;
GetEntityMethodInfo.Invoke(entity, new object[] { primaryKeyValue });
value = entity.GetPrimaryKey();
}
And here is the method:
private static T GetEntity<T>(object primaryKeyValue)
{
T entity = default(T);
new Storage(storage =>
{
entity = storage.Create<T>();
entity.SetPrimaryKey(primaryKeyValue);
storage.Load(entity);
});
return entity;
}
You need to provide or "close" the generic method parameter T, using MethodInfo.MakeGenericMethod ( MSDN )
Something like this:
MethodInfo getEntity =
GetEntityMethodInfo.MakeGenericMethod( ... whatever T should be ... );
var entity = getEntity.Invoke( null, new object[] { primaryKeyValue } );
You should pass null as the first parameter to Invoke because the method is static and so doesn't have an object reference.
I have a class (that I cannot modify) that simplifies to this:
public class Foo<T> {
public static string MyProperty {
get {return "Method: " + typeof( T ).ToString(); }
}
}
I would like to know how to call this method when I only have a System.Type
i.e.
Type myType = typeof( string );
string myProp = ???;
Console.WriteLinte( myMethodResult );
What I've Tried:
I know how to instantiate generics classes with reflection:
Type myGenericClass = typeof(Foo<>).MakeGenericType(
new Type[] { typeof(string) }
);
object o = Activator.CreateInstance( myGenericClass );
However, is this proper to instantiate a class since I am using the static property? How do I gain access to the method if I can't compile time cast it? (System.Object does not have a definition for static MyProperty)
Edit
I realized after posting, the class I'm working with is a property, not a method. I apologize for the confusion
The method is static, so you don't need an instance of an object. You could directly invoke it:
public class Foo<T>
{
public static string MyMethod()
{
return "Method: " + typeof(T).ToString();
}
}
class Program
{
static void Main()
{
Type myType = typeof(string);
var fooType = typeof(Foo<>).MakeGenericType(myType);
var myMethod = fooType.GetMethod("MyMethod", BindingFlags.Static | BindingFlags.Public);
var result = (string)myMethod.Invoke(null, null);
Console.WriteLine(result);
}
}
Well, you don't need an instance to call a static method:
Type myGenericClass = typeof(Foo<>).MakeGenericType(
new Type[] { typeof(string) }
);
Is OK... then, simply:
var property = myGenericClass.GetProperty("MyProperty").GetGetMethod().Invoke(null, new object[0]);
should do it.
typeof(Foo<>)
.MakeGenericType(typeof(string))
.GetProperty("MyProperty")
.GetValue(null, null);
You need something like this:
typeof(Foo<string>)
.GetProperty("MyProperty")
.GetGetMethod()
.Invoke(null, new object[0]);
How do I automate the process of getting an instance created and its function executed dynamically?
Thanks
Edit: Need an option to pass parameters too. Thanks
Do you just want to call a parameterless constructor to create the instance? Is the type specified as a string as well, or can you make it a generic method? For example:
// All error checking omitted. In particular, check the results
// of Type.GetType, and make sure you call it with a fully qualified
// type name, including the assembly if it's not in mscorlib or
// the current assembly. The method has to be a public instance
// method with no parameters. (Use BindingFlags with GetMethod
// to change this.)
public void Invoke(string typeName, string methodName)
{
Type type = Type.GetType(typeName);
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod(methodName);
method.Invoke(instance, null);
}
or
public void Invoke<T>(string methodName) where T : new()
{
T instance = new T();
MethodInfo method = typeof(T).GetMethod(methodName);
method.Invoke(instance, null);
}
To invoke a constructor, Activator.CreateInstance will do the trick. It has a bunch of overloads to make your life easier.
If your constructor is parameterless:
object instance = Activator.CreateInstance(type)
If you need parameters:
object instance = Activator.CreateInstance(type, param1, param2)
To invoke, a method, once you have the Type object you can call GetMethod to get the method, and then Invoke (with or without parameters) to invoke it. Should you need it, Invoke will also give you the return value of the function you're calling (or null if its a void method),
For a slightly more detailed sample (paste into a console app and go):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
namespace Test
{
public static class Invoker
{
public static object CreateAndInvoke(string typeName, object[] constructorArgs, string methodName, object[] methodArgs)
{
Type type = Type.GetType(typeName);
object instance = Activator.CreateInstance(type, constructorArgs);
MethodInfo method = type.GetMethod(methodName);
return method.Invoke(instance, methodArgs);
}
}
class Program
{
static void Main(string[] args)
{
// Default constructor, void method
Invoker.CreateAndInvoke("Test.Tester", null, "TestMethod", null);
// Constructor that takes a parameter
Invoker.CreateAndInvoke("Test.Tester", new[] { "constructorParam" }, "TestMethodUsingValueFromConstructorAndArgs", new object[] { "moo", false });
// Constructor that takes a parameter, invokes a method with a return value
string result = (string)Invoker.CreateAndInvoke("Test.Tester", new object[] { "constructorValue" }, "GetContstructorValue", null);
Console.WriteLine("Expect [constructorValue], got:" + result);
Console.ReadKey(true);
}
}
public class Tester
{
public string _testField;
public Tester()
{
}
public Tester(string arg)
{
_testField = arg;
}
public void TestMethod()
{
Console.WriteLine("Called TestMethod");
}
public void TestMethodWithArg(string arg)
{
Console.WriteLine("Called TestMethodWithArg: " + arg);
}
public void TestMethodUsingValueFromConstructorAndArgs(string arg, bool arg2)
{
Console.WriteLine("Called TestMethodUsingValueFromConstructorAndArg " + arg + " " + arg2 + " " + _testField);
}
public string GetContstructorValue()
{
return _testField;
}
}
}
Assuming that the method you want to invoke does not take any parameters:
public void InvokeMethod(Type type, string methodName)
{
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
method.Invoke(instance, null);
}
I think your problem is little too generic here, I am providing a solution with certain assumptions here.
Assumption: you have a typeName (string), methodName (string), and a parameter (of SomeType).
public static void InvokeMethod(string typeName, string methodName, SomeType objSomeType) {
Type type = Type.GetType(typeName);
if(type==null) {
return;
}
object instance = Activator.CreateInstance(type); //Type must have a parameter-less contructor, or no contructor.
MethodInfo methodInfo =type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public);
if(methodInfo==null) {
return;
}
methodInfo.Invoke(instance, new[] { objSomeType });
}
let me know know if my assumptions are wrong.
To pass the parameters dynamically
Here I have taken params string[] args, because different functions have different number of parameters so.
public void Invoke(string typeName,string functionName,params string[] args)
{
Type type = Type.GetType(typeName);
dynamic c=Activator.CreateInstance(type);
//args contains the parameters(only string type)
type.InvokeMember(functionName,BindingFlags.InvokeMethod,null,c,args);
}