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);
}
}
Related
From Java I've used the below code to invoke method. Pass the Instance of the class where the method is and then execute.
Context context; //Assuming the passed Instance is initialized here
Class c = Class.forName(context.getClass().getName()); //Get the class name including it's package and initialized here
Method m = c.getMethod("thisMethod", String.class, String.class); //Initialize the Method name and it's parameter type
Object t = c.newInstance();
m.invoke(t,"data1", "data2"); //Invoke the method with 2 string
I would like to convert the above code in C#. I've tried to search and I found this link and it's confused me on how can I use the instance I've passed. so far I have the below code in C#.
class Program{
static InvokerClass ic;
private static Program programInstance = new Program();
static void Main(string[] args){
ic = new InvokerClass(programInstance);
ic.StartInvokeExample("Hello","World!");
}
//Call this method later
public static void thisMethod(String data1, String data2) {
Console.WriteLine("DATA1=>" + data1 + ", DATA2=>"+data2);
}
}
class InvokerClass{
private Object objInstance;
public InvokerClass(Object obj){
this.objInstance = obj; //Get the passed Instance and use this to determine the Class Name
}
//Do invoking here
public void StartInvokeExample(String data1, String data2){
Type t = Type.GetType("? ? ?"); //I wanted to use the `objInstance` to determine the Class name
ConstructorInfo cons = t.GetConstructor(Type.EmptyTypes);
object classObject = cons.Invoke(new object[] { });
MethodInfo m = t.GetMethod("thisMethod");
m.Invoke(classObject, new object[] { data1, data2 });
}
}
From InvokerClass I would like to used the objInstance to initialize the Class name but I don't know how. And so far I don't know if I'm doing it in proper way.
This should do it for you:
class InvokerClass
{
private Object objInstance;
public InvokerClass(Object obj)
{
if (obj == null) throw new ArgumentNullException("obj must not be null");
this.objInstance = obj; //Get the passed Instance and use this to determine the Class Name
}
//Do invoking here
public void StartInvokeExample(String data1, String data2)
{
Type t = objInstance.GetType();
object classObject = Activator.CreateInstance(t);
MethodInfo m = t.GetMethod("thisMethod");
m.Invoke(classObject, new object[] { data1, data2 });
}
}
Note: you won´t need to get the constructor, simply use Activator.CreateInstance. Also take care to verify your passed object is not null to avoid a NullReferenceÈxception when trying to call objInstance.GetType().
You can pass in the object instance, but I would probably change it to use a generic instead. Although you are passing in the program object, doing it this way would provide a little more flexibility, because you don't need a an instantiated object to create a new one. You could also create an overload and get both. In your example, I would change the methods to static since you don't need an instantiated object in your example.
class Program
{
private static Program programInstance = new Program();
static void Main(string[] args)
{
InvokerClass.StartInvokeExample<Program>("Hello", "World!");
}
public static void thisMethod(String data1, String data2)
{
Console.WriteLine("DATA1=>" + data1 + ", DATA2=>" + data2);
}
}
class static InvokerClass
{
//Do invoking here
public void StartInvokeExample<T>(String data1, String data2)
where T : new()
{
Type t = typeof(T);
ConstructorInfo cons = t.GetConstructor(Type.EmptyTypes);
object classObject = cons.Invoke(new object[] { });
MethodInfo m = t.GetMethod("thisMethod");
m.Invoke(classObject, new object[] { data1, data2 });
}
public static StartInvokeExample
(Type t, String data1, String data2)
{
ConstructorInfo cons = t.GetConstructor(Type.EmptyTypes);
object classObject = cons.Invoke(new object[] { });
MethodInfo m = t.GetMethod("thisMethod");
m.Invoke(classObject, new object[] { data1, data2 });
}
}
I am struggling to describe this problem I have, but here it is:
Suppose I now have the type of a property on one member of a class (instance):
Type t = propertyInfo.PropertyType;
How do I declare or setup some variable, in order to receive a method call result later, using the out keyword?
t value; // Obviously doesn't compile, How do I declare this?
// or this?
//var value = default(t); // doesn't work
someObject.GetData(out value);
The premise here is that I don't own someObject and I am stuck with this method call signature.
If there is for example a class:
internal class Test
{
public void GetData(out int value)
{
value = 42;
}
}
The method can be called with Invoke() passing object[] as arguments:
var obj = new Test();
var type = obj.GetType();
var m = type.GetMethod("GetData");
var pars = new object[] { null };
m.Invoke(obj, pars);
I may be misunderstanding something about the complexity of the problem here, but, if you have a compile time instance of someObject, you can wrap the evil up like this:
class OutWrap<T,U> where T : U
{
private readonly SomeObject<T> obj;
public OutWrap(SomeObject<T> obj)
{
this.obj = obj;
}
public T Value
{
get
{
T t;
obj.GetData(out t);
return t;
}
}
}
and use it:
var evil = new SomeObject<int>(); // or however/whereever you get it from
var wrap = new OutWrap<int, int>(evil);
var output = wrap.Value;
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 have created an instance called input that is of type:
public class TestInput
{
public int TesTInt { get; set; }
}
I use this in this function:
public static class TestClass
{
public static string TestFunction()
{
var testInput = new TestInput();
string res = ServicesManager.Execute<string>((object) testInput);
return res;
}
}
The Execute function is here:
public static OUT Execute<OUT>(object input)
where OUT : class
{
var method = //getting method by reflection
object[] arr = new object[] { input };
return method.Invoke(null, arr) as OUT; //Error is triggered here
}
The method that I invoke is this one:
public static string TestFunctionProxy(object[] input)
{
var serviceInput = input[0] as TestInput;
//rest of code
}
I received the error in the title. (XXX - "TestInput" type)
What's happening and what is causing this error?
Note: method is static so no instance is required for the first parameter. Please correct me if I'm wrong.
Any help is appreciated.
EDIT: Updated the question with some more code for a complete example.
You are passing the wrong arguments to the method. It wants an object[] and you are giving a simpe object. This is how to fix it:
object[] arr = new object[] { new object[] { input } };
The 'outer' object[] is the parameter for Invoke, the 'inner' array is the parameter for your method.
I am trying to write a generic extension method targeting .Net 4.5. I want to test a type to see if TryParse is defined in the class. If yes, invoke the TryParse method at runtime.
Here is my implemenation.
using System;
using System.Linq;
using System.Reflection;
namespace ExtentionMethodPractises
{
static public class ExtensionMethods
{
public static T ParseOrDefault<T>(this T targetType, string source) where T : new()
{
if (targetType.GetType().GetMethods(BindingFlags.Static|BindingFlags.Public).Any(methodInfo => methodInfo.Name == "TryParse"))
{
var result = new T();
var parameterTypes = new Type[] {source.GetType(), targetType.GetType()};
var parameterModifier = new ParameterModifier(2);
parameterModifier[0] = false;
parameterModifier[1] = true;
var tryParseMethod = targetType.GetType().GetMethod("TryParse", parameterTypes, new ParameterModifier[] { parameterModifier});
tryParseMethod.Invoke(null, new object[] {source, result});
return result;
}
return new T();
}
}
}
I tested my extension method with System.UInt16 which has TryParse methods. I got a nullref on the tryParseMethod after reflection.
I implemented a dummy test class ReflectorTarget to test my extension method. I got a null reference too. It seems that the reflector is incapable of search methods has pass-by-reference parameter(s).
namespace ExtentionMethodPractises
{
public class ReflectorTarget
{
public static bool TryParse(string source, out ReflectorTarget output)
{
output = new ReflectorTarget();
return true;
}
public static bool TryParse(string source, bool isReally, out ReflectorTarget output)
{
output = new ReflectorTarget();
return true;
}
}
}
Lastly, I changed my dummy test class implementation as follows. Suddenly, the reflector will pick up the TryParse method at runtime. All I did is change the second parameter from a pass-by-reference parameter to a normal parameter.
namespace ExtentionMethodPractises
{
public class ReflectorTarget
{
public static bool TryParse(string source, ReflectorTarget output)
{
return true;
}
public static bool TryParse(string source, bool isReally, out ReflectorTarget output)
{
output = new ReflectorTarget();
return true;
}
}
}
Question: How do I reflect a method (static/non-static) that has a pass-by-reference parameter in C#? Thank you.
I think you want this:
namespace ExtentionMethodPractises
{
static public class ExtensionMethods
{
public static T ParseOrDefault<T>(this T targetType, string source)
where T : new()
{
if (targetType.GetType()
.GetMethods(BindingFlags.Static|BindingFlags.Public)
.Any(methodInfo => methodInfo.Name == "TryParse"))
{
var result = new T();
var parameterTypes = new Type[] {source.GetType(),
//Key change here
targetType.GetType().MakeByRefType()};
var tryParseMethod = targetType.GetType()
.GetMethod("TryParse", parameterTypes);
tryParseMethod.Invoke(null, new object[] {source, result});
return result;
}
return new T();
}
}
}
see MakeByRefType:
Returns a Type object that represents the current type when passed as a ref parameter (ByRef parameter in Visual Basic).
tryParseMethod.Invoke(null, new object[] {source, result});
Damien got you unblocked on passing the correct type, but you still need to invoke the method correctly. A method that takes a ref argument will update the value in the passed object[], it is not going to modify your result variable. And you are interested in the return value of this method. Also notable is that ParameterModifier is actually ignored for .NET methods. Which collapses your method down to:
public static T ParseOrDefault<T>(this T targetType, string source) where T : new() {
var parameterTypes = new Type[] { source.GetType(), targetType.GetType().MakeByRefType() };
var tryParseMethod = targetType.GetType().GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, null, parameterTypes, null);
if (tryParseMethod != null) {
var args = new object[] { source, null };
var retval = (bool)tryParseMethod.Invoke(null, args);
if (retval) return (T)args[1];
}
return new T();
}