I want to modify the below code to be able to use a private method
//use reflection to Load the data
var method =
typeof(MemberDataFactory)
.GetMethod("LoadData")
.MakeGenericMethod(new [] { data.GetType() })
.Invoke(this, null);
Ive tried the following with no luck:
//use reflection to Load the data
var method =
typeof(MemberDataFactory)
.GetMethod("LoadData")
.MakeGenericMethod(new [] { data.GetType() })
.Invoke(this, BindingFlags.Instance | BindingFlags.NonPublic, null , null, null);
Also what is "var" in terms of this code? Id prefer to specify its type instead of using var.
Thanks!
You want to use this overload of Type.GetMethod(), which is where you pass your binding flags. The default .GetMethod(string) only looks for public methods, so it returns null, hence your null reference exception.
Your code should be something more like:
var method =
typeof(MemberDataFactory)
.GetMethod("LoadData", BindingFlags.Instance | BindingFlags.NonPublic) // binding flags go here
...
Related
I previously had an issue with using reflection that you can see here.
After having received an answer to the question and attempted to implement it to my project I seem to have hit yet another wall.
Basically I have this code:
String[] arr = {"", conStr, ""};
var myType = (typeof(JaberoDC.JaberoDC.JaberoDC));
var method = myType.GetMethods(param, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Single(mi => mi.ReturnType == typeof(DataSet));
var subject = Activator.CreateInstance(myType);
var result = method.Invoke(subject, arr);
DataSet ds = (DataSet)result;
Where param is a String.
However, it doesn't seem to work as intended.
The line
var method = myType.GetMethods (param, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Single(mi => mi.ReturnType == typeof(DataSet));
Throws the error
Unkown method GetMethods(string, System.Reflection.BindingFlags) of
System.Type
And
mi => mi.ReturnType == typeof(DataSet));
Throws this error:
Unkown type of variable mi
Could anyone help me with the correct initialization of my method variable. I've looked around on Google to see if I could possibly find something to at least point me in the right direction. My previous code (again, see the other question) compiled and ran, but threw an ambiguous match found error.
EDIT:
Changed my code to be more like the answer below. However I'm getting an error while debugging it:
targetparametercountexception parameter count mismatch
That is happening on this line:
var result = method.Invoke(subject, arr);
From reading about reflection online it seems like you should be passing in an array of parameters that the method you invoke requires (in my case the array). In a different class I use this (which works absolutely fine; I'm attempting to invoke the exact same method):
DataSet ds = jdc.FETCHvw_WorksiteEntry("", conStr, "");
End of EDIT1.
This does what you're attempting, but I don't think it's quite what you want.
var method = myType.GetMethods(
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Single(mi =>
mi.ReturnType == typeof(DataSet)
&& string.Equals(mi.Name, param, StringComparison.OrdinalIgnoreCase));
This gets you a method and you know that it returns a DataSet, but there's no guarantee that you can invoke it with the argument(s) you have.
This would be better:
var method = myType.GetMethod(param,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
null, new Type[] {typeof (string)}, null);
Where the array {typeof(string)} is an array of the parameter types the method receives. That way you're looking for exactly the method you want, not just one with the correct return type.
(I wasn't clear on what the arguments for the method are. If it's two strings then that would be new Type[] {typeof (string), typeof(string)}. If it's an array of strings then new Type[] {typeof (string[])}.
I have a static class with private functions, I want to get all functions except one. I tried using Ignorecase but i get an overload exception... I do it exactly like many examples online but I get an error and I dont know why...am I missing something?
//Example
static MethodInfo[] allFuncs ;
static Type myType = typeof(myClass);
allFuncs = myType.GetMethods("innerFunction",
BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Static);
If you want all methods except one with a particular name, you can use Enumerable.Where to filter:
allFuncs = typeof(MyClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
.Where(method => !method.Name.Equals(
"innerFunction", StringComparison.OrdinalIgnoreCase));
First, GetInvocationList() won't work, because I want to be able to get to them from outside the class. I assume it will work with some reflection magic, and that's what I'm trying to figure out.
Here's what I have right now:
fooEventDispatcher.GetType().GetField("FooEvent", BindingFlags.Instance | BindingFlags.NonPublic);
var field = fieldInfo.GetValue(fooEventDispatcher);
I just don't know what to do with field. Any ideas?
This should work:
var fieldInfo = fooEventDispatcher.GetType().GetField(
"FooEvent", BindingFlags.Instance | BindingFlags.NonPublic);
var eventDelegate = fieldInfo.GetValue(fooEventDispatcher) as MulticastDelegate;
if (eventDelegate != null) // will be null if no subscribed event consumers
{
var delegates = eventDelegate.GetInvocationList();
}
Also you should use typeof(SomeFooClass) instead of fooEventDispatcher.GetType() if the type is already known at compile time (which I assume it is).
Question from a Reflection newbie. I have a method in a Windows Form:
private void handleOrderCode()
{
//...do stuff
}
Which I am trying to call in the following manner:
Type t = this.GetType();
MethodInfo mi = t.GetMethod("handleOrderCode");
if (mi != null) mi.Invoke(this, null);
I have confirmed that "this" is not null. The space where the string "handleOrderCode" has been hardcoded is to be replaced with a string variable when this works. However, at present "mi" is always null when it evaluates in the if statement in the final line.
So what am I doing wrong?
You need to specify binding flags:
using System.Reflection;
t.GetMethod("handleOrderCode", BindingFlags.Instance | BindingFlags.NonPublic)
Because overload without any flag means:
BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance
i.e. will not return any non-public (private, protected, etc) members.
The parameterless overload of Type.GetMethod only looks for public methods:
Searches for the public method with the specified name.
You need to specify an appropriate BindingFlags value to another overload instead:
MethodInfo method = t.GetMethod("handleOrderCode",
BindingFlags.Instance | BindingFlags.NonPublic);
Note that you need to specify "instance" or "static" here (or both), not just "non-public". If you want to look for public methods as well, you have to include that too.
Another alternative is just to make your method public :)
(Additionally, I'd suggest renaming it to HandleOrderCode to be more conventional, idiomatic C#.)
try:
Type t = this.GetType();
MethodInfo mi = t.GetMethod("handleOrderCode",
BindingFlags.NonPublic | BindingFlags.Instance);
if (mi != null) mi.Invoke(this, null);
I am trying to using Emit to generate mapping code (mapping properties from one object to another). I have it working if the two types match (source and target), but I can't get it to work in an instance where the types don't match and I need to call a static method in the mapping. Below is code that I thought would work but I get a method does not exist error even though it does. I am guessing my emit call is incorrect. Any suggestions?
foreach (var map in maps)
{
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Callvirt, map.SourceProperty.GetGetMethod(), null);
if (map.SourceProperty.PropertyType == map.TargetProperty.PropertyType)
il.EmitCall(OpCodes.Callvirt, map.TargetProperty.GetSetMethod(), null);
else if (map.TargetProperty.PropertyType.Name == "ObjectId" && map.SourceProperty.PropertyType.Name.ToLower() == "string") {
var method = typeof(ObjectId).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, new Type[] { typeof(string) }, null);
il.EmitCall(OpCodes.Callvirt, method , null);
}
}
il.Emit(OpCodes.Ret);
You should be able to call it by using EmitCall with OpCodes.Call instead of CallVirt.
This is the line that's throwing the error?
var method = typeof(ObjectId).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, new Type[] { typeof(string) }, null);
Perhaps you could try
Type ObjectIDType = typeof(ObjectId);
MethodInfo method = ObjectIDType.GetMethod("Parse", new Type[] { typeof(string) });
Perhaps parse takes an object as its parameter instead of a string?
What is the error message?