Reputation: 70983
Imagine I have the following class:
class Cow {
public static bool TryParse(string s, out Cow cow) {
...
}
}
Is it possible to call TryParse
via reflection? I know the basics:
var type = typeof(Cow);
var tryParse = type.GetMethod("TryParse");
var toParse = "...";
var result = (bool)tryParse.Invoke(null, /* what are the args? */);
Upvotes: 12
Views: 6479
Reputation: 39
Sorry for the bump, but the previous answers to this thread got me started but did not fully answer what I needed. Here's the rest of the answer I figured out:
When working with reflection, in
, out
, and ref
method parameter types are all the same kind of special "ref" type which you can get by doing typeof(MyType).MakeByRefType()
. When searching for methods with matching parameter types, MyType
and ref MyType
are considered to be not equal!
Below code is what I did to add a TryParse method to my class that holds a generic struct TData
. My TryParse reflectively searches for TData
's TryParse and tries to invoke that, instead of having to manually implement a TryParse override method for each held TData
struct type.
(try;catch; and some other stuff removed for readability)
public bool TryParse(string stringToParse, out TData outResult)
{
// Given 'TData' is the type we want to try to invoke TryParse() on...
const string METHOD_NAME = "TryParse";
Type type = typeof(TData);
Type[] methodParams = new[] { typeof(string), type.MakeByRefType() }; //GetMethod() will fail without MakeByRefType() here!
MethodInfo method = type.GetMethod(METHOD_NAME, BindingFlags.Static | BindingFlags.Public, null, methodParams, null);
TData outResult = default(TData);
if (method == null)
return false;
// TryParse "out TData" gets written to object[1] array after invoke.
object[] invokeParams = new object[] { stringToParse, outResult };
object result = method.Invoke(null, invokeParams);
if (result is bool didParse && didParse)
{
outResult = (TData)invokeParams[1]; //Read what the method wrote as "out TData"
return true; // return parse success
}
return false;
}
Upvotes: 1
Reputation: 20066
You can do something like this:
static void Main(string[] args)
{
var method = typeof (Cow).GetMethod("TryParse");
var cow = new Cow();
var inputParams = new object[] {"cow string", cow};
method.Invoke(null, inputParams);
// out parameter value is then set in inputParams[1]
Console.WriteLine( inputParams[1] == null ); // outputs True
}
class Cow
{
public static bool TryParse(string s, out Cow cow)
{
cow = null;
Console.WriteLine("TryParse is called!");
return false;
}
}
Upvotes: 10