it may be a duplicate of
How to dynamically call a class' method in .NET?
and of
how to achieve calling a function dynamically, thats right the function to be called is decided from database values, using c#
but the above two have solutions which as the answers said are complicated, not for a beginner i guess.
and
both solutions contain "type" which from the code i think is for defining the class the method belongs to.
like
static void caller(String myclass, String mymethod)
{
// Get a type from the string
Type type = Type.GetType(myclass);
// Create an instance of that type
Object obj = Activator.CreateInstance(type);
// Retrieve the method you are looking for
MethodInfo methodInfo = type.GetMethod(mymethod);
// Invoke the method on the instance we created above
methodInfo.Invoke(obj, null);
}
but my initial web site, only contains one class common to all the functions,
a database which has "function name" "func id"
supposed :- function name exactly same as that in code
i only want to achieve the following
get the string value of function name according to the id mentioned in the text box
now call that function, whose name is in the string variable
problem
the methodinfo, needs the "type.GetMethod(mymethod);"
..
In order to call a function you need to specify the type this function is declared on. If all functions you are going to call are declared on a common class you could do the following:
static void CallFunc(string mymethod)
{
// Get a type from the string
Type type = typeof(TypeThatContainsCommonFunctions);
// Create an instance of that type
object obj = Activator.CreateInstance(type);
// Retrieve the method you are looking for
MethodInfo methodInfo = type.GetMethod(mymethod);
// Invoke the method on the instance we created above
methodInfo.Invoke(obj, null);
}
If the functions you are going to call are static you don't need an instance of the type:
static void CallFunc(string mymethod)
{
// Get a type from the string
Type type = typeof(TypeThatContainsCommonFunctions);
// Retrieve the method you are looking for
MethodInfo methodInfo = type.GetMethod(mymethod);
// Invoke the method on the type
methodInfo.Invoke(null, null);
}
I see 2 solutions:
you need to map function id to
real function name
call
type.GetMethods() to get list of all
methods and choose right one
Related
Assume you have an dynamic library and you want to collect all its methods via System.Reflection namespace.
Now, if a method is an instance method, you want to:
load it via reflection
convert it into a static method, whose signature contains one more input parameter of the type of the declaring instance.
The conversion below summarises the second point, but I am having troubles with that.
Problems are two:
The return of Delegate.CreateDelegate(delegateType, method).Method has the correct arguments, but the method is not static.
Sometimes it fails to bind the method, although the parameters are correct:
System.ArgumentException
"Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type."
The method is below:
public static MethodInfo ToStatic(this MethodInfo method)
{
MethodInfo staticmethod;
if (method.IsStatic)
return method;
List<Type> parametersTypes = method.GetParameters().Select(x => x.ParameterType).ToList();
parametersTypes.Insert(0, method.DeclaringType);
parametersTypes.Add(method.ReturnType);
Type delegateType = Expression.GetDelegateType(parametersTypes.ToArray());
staticmethod = Delegate.CreateDelegate(delegateType, method).Method;
return staticmethod.IsStatic ? staticmethod : null;
}
Is there any way to force create a Delegate whose method is static?
If so, what static class would hold that method?
I have got one method in class
public JObject InvokeMethod(string a_sMethod, params object[] a_params)
And I need to call this method in bool Test() in another class
protected override bool Test ()
{
logger.Write("Test1");
WebServer ws = new WebServer();
ws.InvokeMethod();
}
I need to call these two params: a_sMethod and a_params in other class.
Have anyone some idea how to do that ?
public string a_sMethod{get; set;}
does not work in this case. I get an error: There is no argument that correspondsto the required formal parameter 'a_sMethod' .
I get an error: There is no argument that correspondsto the required
formal parameter 'a_sMethod' .
error occurs here because you haven't specified the correct arguments for the method.
ws.InvokeMethod();
The method signature below expects a string and any number of data to be passed in:
public JObject InvokeMethod(string a_sMethod, params object[] a_params)
Example:
ws.InvokeMethod("testing", 1,2,3,4,5,5); // this is just for illustration, you can pass in the data you want to work with.
There are disadvantages of using object type as params array but it's beyond the scope of this question, so I will let that pass.
UPDATE
if you want to use properties, that's also simple.All you have to do is just set the data for that particular property and pass them in as the InvokeMethod(string a_sMethod, params object[] a_params) method parameters expect.
I am wondering if it is possible to use a classes method when you only know the classes name by it's string value.
Let's say I have a class and within class I have a static method like
public class SomeClass
{
public static string Do()
{
//Do stuff
}
}
And when using class I want to something like
string str = (GetType(SomeClass)).Do();
When using the method I want to give the name of the class as string like I want to give SomeClass as a string.
var t = Type.GetType("MyNamespace.SomeClass");
var m = t.GetMethod("Do");
m.Invoke(null, new object[] { /* Any arguments go here */ });
You're going to have to use reflection throughout; for example:
object result = Type.GetType(typeName).GetMethod(methodName).Invoke(null, args);
Use Type.GetMethod to get the method info object of the method, then call MethodInfo.Invoke to execute it. For static methods, pass null as the first parameter (the object value):
Type type = typeof(SomeClass);
type.GetMethod("Do").Invoke(null, null);
If you don’t know the class name at compile time, you can also use object.GetType, Type.GetType or Assembly.GetType to get the type object at runtime (depending on what information you have available). Then, you can use it in the same way:
Type type = someObject.GetType(); // or Type.GetType("SomeTypeName");
type.GetMethod("Do").Invoke(null, null);
To be on the safe side, make sure to check whether GetMethod actually returns a method, so you have some confirmation that the method exists on that type then.
Suppose I have a method
public void Whatever<T>() { ... }
suppose I have a type in the form of a string
var myType = "System.String";
Normally, I'd call the method like:
Whatever<string>();
But I'd like to be able to call it using myType somehow. Is this possible?
I know this doesn't work, but conceptually:
Whatever<Type.GetType(myType)>();
You can use Reflection and MethodInfo.MakeGenericMethod for this
Reflect the method that you want to call to get the MethodInfo, then make it generic and Invoke it.
Something like this (notice that this is from the top of my head (no VS here), it might not be perfect yet but should get you started):
Type type = myObject.GetType();
MethodInfo method = type.GetMethod("NameOfMethod");
MethodInfo genericMethod = method.MakeGenericMethod(typeOf(string));
genericMethod.Invoke(myObject, new object[] { "theString" } );
You can create an instance via Reflection (or provide both generic and non-generic Whatever type). Of course Reflection is slow (and you can have only an object or base class reference). Often the generic type can be just a specialization of the non-generic one.
I am loading a dll using loadfrom and iterating thru the methods to find ones that match a signature. When I find it I want to assign it as a delegate so I can call it later. This is what I am doing...
foreach (MethodInfo method in methodInfos)
{
if (method.GetParameters().Length == 2)
{
ParameterInfo[] parameters = method.GetParameters();
if (parameters[0].ParameterType.Name == "Command"
&& parameters[1].ParameterType.Name == "ExposedVariables")
{
aoc.methodinfo = method;
Command.delCmdMethod del = (Command.delCmdMethod)
Delegate.CreateDelegate(typeof(Command.delCmdMethod)
, null
, method);
}
}
}
Problem is - the delegate assignment does not work. I get an error binding to target method.
I read on the web that the the 2nd parameter could be the issue if the method is not static. My method is NOT static.
Any ideas?
Although Miky Dinescu's answer might be helpful, it is only partially correct. There does exist an overload for Delegate.CreateDelegate which will most likely help you.
First off, Miky is right that you have to pass the instance as the second parameter, but this is only the case if you want to create what is called a closed delegate. This means an instance is bound to the delegate along with the method. In practice this means when calling the delegate, it will always operate on the same instance.
From your question, it looks like that isn't what you are trying to achieve. If you want to be able to pass the instance along when calling the delegate, you have to use the CreateDelegate( Type type, MethodInfo method ) overload. This allows you to create what is called an open instance delegate.
Since you'll have to pass the instance along when calling the method, this means there is an extra parameter required in your delegate type. The first parameter of your delegate type will need to correspond to the type of the class in which the method is contained.
Example:
MethodInfo toUpperMethod
= typeof( string ).GetMethod( "ToUpper", new Type[] { } );
Func<string, string> toUpper
= (Func<string, string>)Delegate.CreateDelegate(
typeof( Func<string, string> ), toUpperMethod );
string upper = toUpper( "test" ); // Will result in "TEST".
Since - just like you - I found these overloads to be unclear, I created two helper functions to clearly separate creating a 'normal' delegate or an open instance delegate. This code, along with a more thorough discussion can be found in my blog post.
If the method is not static then you need to pass in a reference to an instance of the class who's method you are going to be invoking using the delegate.
If you don't know which instance you will be using at the time when you are attempting to create the delegate you will need to store the type and method information for later and then create the Delegate after you have the instance of the class.
EDIT
To answer your comment, the object that you need to pass is an object of the type that contains the method your are trying to bind your delegate to. So based on your code sample it's not the Command object but an object of the class from the DLL.
So, let's say that you have this .NET assembly DLL: myassembly.dll. The assembly contains the following class:
namespace MyNamespace
{
public class SomeClass
{
public SomeClass()
{
}
public void Method1(object Command, object ExposedVariables)
{
}
public void Method2(object Command, object ExposedVariables)
{
}
}
You would need to create an instance of the class SomeClass before you could create delegates bound to Method1 or Method2 of that class. So, the code which creates the delegate should look like this:
// assuming that method info is a MethodInfo contains information about the method
// that you want to create the delegate for, create an instance of the class which
// contains the method..
object classInstance = Activator.CreateInstance(methodInfo.DeclaringType);
// and then create the delegate passing in the class instance
Delegate.CreateDelegate(typeof(Command.delCmdMethod), classInstance, methodInfo);