i wrote this code:
MethodInfo method2 = typeof(IntPtr).GetMethod(
"op_Explicit",
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
null,
new Type[]{
typeof(IntPtr),
},
null
);
if I try to run i get an ambiguousmatchexception, how can i solve this problem? thanks
The method i am trying to get is op_Explicit(intptr) return value int32
There are no standart overloads for choosing between methods with different types. You must find method by yourself. You can write your own extension methods, like this:
public static class TypeExtensions {
public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingAttr, Type[] types, Type returnType ) {
var methods = type
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(mi => mi.Name == "op_Explicit")
.Where(mi => mi.ReturnType == typeof(int));
if (!methods.Any())
return null;
if (methods.Count() > 1)
throw new System.Reflection.AmbiguousMatchException();
return methods.First();
}
public static MethodInfo GetExplicitCastToMethod(this Type type, Type returnType )
{
return type.GetMethod("op_Explicit", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, new Type[] { type }, returnType);
}
}
And then use it:
MethodInfo m = typeof(IntPtr).GetExplicitCastToMethod(typeof(int));
Be accurately, there are two defined casts in IntPtr class:
public static explicit operator IntPtr(long value)
public static explicit operator long(IntPtr value)
And no defined casts in System.Int64 class (long is alias of Int64).
You can use Convert.ChangeType for this purposes
There are multiple explicit operators which allow IntPtr as a parameter and they differ only with their return types. Try to use the solution from this question to get the method which you're interested in by specifying not only parameter types but also return type:
Get only Methods with specific signature out of Type.GetMethods()
Related
I want to invoke a class
"***" is the solution that works for me but I want to invoke
THIS IS THE SOLUTION THAT GIVES ME THE ERROR :
Type t = Type.GetType(svClass);
MethodInfo method = t.GetMethod("execute", BindingFlags.instance| BindingFlags.Public);
Ret = (string)method.Invoke(null, new object[] { context.Request});
public string execute(HttpRequest req)
so that I tried to MethodInfo method = t.GetMethod("execute", BindingFlags.instance | BindingFlags.Public);
but it gives me the error "non-static method requires a target"
*** THIS IS THE WORKING SOLUTION FOR STATIC METHOD
Type t = Type.GetType(svClass);
MethodInfo method = t.GetMethod("execute", BindingFlags.static| BindingFlags.Public);
Ret = (string)method.Invoke(null, new object[] { context.Request});
to invoke
public class XXXXX
{
public static string execute(HttpRequest req){}
}
The secret is to change your binding flags to get a MethodInfo that matches the signature of the method you wish to call.
Eg:
public static string execute(HttpRequest req){}
Will be accessed via
MethodInfo method = t.GetMethod("execute", BindingFlags.static| BindingFlags.Public);
However, to access
public string execute(HttpRequest req){}
you need to do
var classObj = new Class();
MethodInfo method = classObj.GetType().GetMethod("execute", BindingFlags.Instance| BindingFlags.Public);
Instance means that the method is a member of a class object, and not of the class type.
(Instance vs Static)
var parameterArray = new object[]{ YourHttpRequestHere};
var result = method.Invoke(classObj,parameterArray);
So remember, if the method belongs to an instance, then you need to grab the method from that instance type, and then you need to invoke it with a reference to the instance variable (classObj) above.
I have A class:
public abstract class A
{
}
And then I have B class that derives from it:
public sealed class B : A
{
public void SomeMethod()
{
var method = this.GetType().GetMethod("AddText");
}
private void AddText(string text)
{
...
}
}
Why is GetMethod returning null?
var methodInfo = this.GetType().GetMethod("AddText", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(string) }, null);
Your method has a parameter, you need to use the overload that accepts a type array for the parameter types and the binding flags.
In .net Method signatures are based on their name, their return type, and their parameters.
So if your method has parameters you have to tell Reflection what parameter types it has via a Type[].
By default, Reflection will only search for public methods.
You need to pass BindingFlags.Instance | BindingFlags.NonPublic.
Question is simple: I'm using reflection to get a value. Then if it's a struct, I'm calling a method FooStruct, else FooClass:
Type type = x.GetType();
foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
var val = fieldInfo.GetValue(value);
object obj = type.IsValueType ? val.FooStruct() : val.FooClass();
fieldInfo.SetValue(x, obj);
}
problem is that FooStruct has a constraint:
public static T FooStruct<T>(this T value) where T : struct
{
//...
}
so question is: is it possible to call a method with struct constraint for an object which contains a boxed struct instance without reflection?
I'd happily be proven wrong by another answer, but I don't think this is possible without resorting even more to reflection. See further below for the reason that makes me suspect this. See end of the answer for a reflection-based solution.
Practical suggestion: I would simply drop the constraint on your FooStruct and FooClass methods, and additionally:
either make them non-generic and accept an argument of type object (which is what val is declared as, anyway). There's no advantage to having these methods be generic if they are only ever passed objects;
or cast val from object to T before invoking FooStruct / FooClass.
Why does it seem impossible to do what you're asking? You are trying to convert an expression that is statically typed object (namely val) into something that is statically typed <T> where T : struct or <T> where T : class (in order to call the respective extension method on such a T). That is, you are trying to dynamically introduce a new type variable inside your foreach loop. Unfortunately, the only way to introduce a type variable is to declare it in advance, i.e. as some generic type parameter T in the method's signature; and then it is not the code inside your method that gets to choose what actual type it stands for—it's the calling code that determines T.
Reflection-based solution:
// determine which method ought to be called based on `val`'s run-time type.
// (for C# 6 and later, use the `nameof` operator instead of hard-coding method names)
Type type = val.GetType();
string fooName = type.IsValueType ? "FooStruct" : "FooClass";
// bind to the generic method and supply the type argument for it:
// (I'm assuming that your extension methods are defined in `FooMethodsClass`.)
MethodInfo fooOpen = typeof(FooMethodsClass).GetMethod(fooName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo foo = fooOpen.MakeGenericMethod(new Type[] { type });
// invoke the generic (extension) method with `val` as the `this` argument:
foo.Invoke(null, new object[] { val });
The dynamic variable support will set T appropriately. I use this trick regularly. Try it like this:
Type type = x.GetType();
foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
dynamic val = fieldInfo.GetValue(value);
object obj = type.IsValueType ? Utilities.FooStruct(val) : Utilities.FooClass(val);
fieldInfo.SetValue(x, obj);
}
Apparently you can call the methods with reflection and they work without a problem:
using System;
using System.Reflection;
namespace DemoDynamicT
{
public static class Utilities
{
public static T FooStruct<T>(this T value) where T:struct
{
return default(T);
}
public static T FooClass<T>(this T value) where T : class
{
return default(T);
}
}
public class Program
{
class TestClass
{
public TestStruct StructField;
}
struct TestStruct
{
public int x;
int y;
}
public static void Main()
{
var x = new TestClass();
Type type = x.GetType();
foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
var val = fieldInfo.GetValue(x);
var methodInfo = typeof(Utilities).GetMethod(fieldInfo.FieldType.IsValueType ? "FooStruct" : "FooClass");
var toBeCalled = methodInfo.MakeGenericMethod(fieldInfo.FieldType);
object obj = toBeCalled.Invoke(null, new [] {val});
fieldInfo.SetValue(x, obj);
}
}
}
}
I don't think you can do this directly. You can try workaround like this:
public static class Utilities
{
public static ValueType FooStruct(this ValueType value)
{
//put your code here
return default(ValueType);
}
public static object FooClass(this object value)
{
//put your code here
return null;
}
public static T FooStruct<T>(this T value) where T: struct
{
return (T) FooStruct(value);
}
public static T FooClass<T>(this T value) where T: class
{
return (T) FooClass(value);
}
}
public class Program
{
class TestClass
{
public TestStruct StructField;
}
struct TestStruct
{
int x;
int y;
}
public static void Main()
{
var x = new TestClass();
Type type = x.GetType();
foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
var val = fieldInfo.GetValue(x);
object obj = fieldInfo.FieldType.IsValueType ? ((ValueType)val).FooStruct() : val.FooClass();
fieldInfo.SetValue(x, obj);
}
//Generic call
var structVar = new TestStruct();
structVar.FooStruct();
}
}
I need to find property inside of generic type. This is an old way (and since my code is dedicated for WinRT I believe I need another approach):
PropertyInfo pi = typeof(TRp).GenericTypeArguments[0].GetProperty(idField, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
I need to achieve the same result using GetRuntimeProperties. This is my approach:
PropertyInfo pi = typeof(TRp).GenericTypeArguments[0].GetRuntimeProperties().Single(p => p.Name.ToUpper() == idField.ToUpper()...
as you can see I implemented IgnoreCase in a custom way, probably it can be done better?
How can I implement remaining BindingFlags?
Thank you!
You actually dont need to. This is how Type.GetRuntimeProperties is implemented:
public static IEnumerable<PropertyInfo> GetRuntimeProperties(this Type type)
{
CheckAndThrow(type);
IEnumerable<PropertyInfo> properties = type.GetProperties(everything);
return properties;
}
Where everything is defined as following:
private const BindingFlags everything = BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Static;
Which means it will already look for your required flags.
Edit:
If you want to specify BindingFlags yourself, you can write your own custom extension method:
public static class TypeExtensions
{
public static IEnumerable<PropertyInfo> GetAllProperties(this TypeInfo type,
BindingFlags bindingFlags)
{
var propertyInfos = type.GetProperties(bindingFlags);
var subtype = type.BaseType;
if (subtype != null)
list.AddRange(subtype.GetTypeInfo().GetAllProperties(bindingFlags));
return propertyInfos.ToArray();
}
}
Note this hasn't been tested. It is merely an attempt to show you that you can do it yourself.
I want to know what is fastest way to get value (only for this problem) from an object`s property ?
after some searching I saw a post from #MarkGravell in this site
He wrote this code :
using System;
using System.Reflection;
using System.Reflection.Emit;
public class Foo
{
public Foo(int bar)
{
Bar = bar;
}
private int Bar { get; set; }
}
static class Program {
static void Main()
{
var method = new DynamicMethod("cheat", typeof(int),
new[] { typeof(object) }, typeof(Foo), true);
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, typeof(Foo));
il.Emit(OpCodes.Callvirt, typeof(Foo).GetProperty("Bar",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
).GetGetMethod(true));
il.Emit(OpCodes.Ret);
var func = (Func<object, int>)method.CreateDelegate(
typeof(Func<object, int>));
var obj = new Foo(123);
Console.WriteLine(func(obj));
}
}
OR
var method = typeof(Foo).GetProperty("Bar",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.GetGetMethod(true);
var func = (Func<Foo, int>)
Delegate.CreateDelegate(typeof(Func<Foo, int>), method);
I changed it to
var pt = propertyInfo.PropertyType; // I dont know what is Type
var method = pt.GetProperty("Bar",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.GetGetMethod(true);
var func = (Func<Foo, object>) // I dont know what is return type so set object !!!
Delegate.CreateDelegate(typeof(Func<Foo, object>), method); // I want get value as object ?!!!
return func(entity).ToString(); // cast return value to string
but I got an exception
Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
I dont know what is my property type It can be anything How customize code for this purpose ?
If anyone can help me in better way (fastest way) without property Type restriction please introduce it
The Delegate.CreateDelegate will not work in this case, because you have to cast the resulting delegate to some known type, otherwise all you have is DynamicInvoke which is not better than direct invocation of PropertyInfo (see here explanation by Marc Gravell).
The most generic way I've seen which does not involve lambda expressions (like
Sriram Sakthivel suggested) is shown by Jon Skeet here. Building on his approach and the fact we can get the actual property return type from PropertyInfo, we can invent something custom-tailored for properties invocation.
First, we define an interface:
public interface IPropertyCallAdapter<TThis>
{
object InvokeGet(TThis #this);
//add void InvokeSet(TThis #this, object value) if necessary
}
Then, an implementation of the interface:
public class PropertyCallAdapter<TThis, TResult> : IPropertyCallAdapter<TThis>
{
private readonly Func<TThis, TResult> _getterInvocation;
public PropertyCallAdapter(Func<TThis, TResult> getterInvocation)
{
_getterInvocation = getterInvocation;
}
public object InvokeGet(TThis #this)
{
return _getterInvocation.Invoke(#this);
}
}
The InvokeGet method looks mostly like the one Jon Skeet uses.
Now, to the "magic" part. We define a service which will build and cache an instance of the provider. It looks like this:
public class PropertyCallAdapterProvider<TThis>
{
private static readonly Dictionary<string, IPropertyCallAdapter<TThis>> _instances =
new Dictionary<string,IPropertyCallAdapter<TThis>>();
public static IPropertyCallAdapter<TThis> GetInstance(string forPropertyName)
{
IPropertyCallAdapter<TThis> instance;
if (!_instances.TryGetValue(forPropertyName, out instance))
{
var property = typeof(TThis).GetProperty(
forPropertyName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo getMethod;
Delegate getterInvocation = null;
if (property != null && (getMethod = property.GetGetMethod(true)) != null)
{
var openGetterType = typeof(Func<,>);
var concreteGetterType = openGetterType
.MakeGenericType(typeof(TThis), property.PropertyType);
getterInvocation =
Delegate.CreateDelegate(concreteGetterType, null, getMethod);
}
else
{
//throw exception or create a default getterInvocation returning null
}
var openAdapterType = typeof(PropertyCallAdapter<,>);
var concreteAdapterType = openAdapterType
.MakeGenericType(typeof(TThis), property.PropertyType);
instance = Activator
.CreateInstance(concreteAdapterType, getterInvocation)
as IPropertyCallAdapter<TThis>;
_instances.Add(forPropertyName, instance);
}
return instance;
}
}
Here, without knowing at compile time the exact TResult type, we create the adapter and cache it for subsequent usage in order to prevent heavy reflection calls in the future.
That's it. You can use it in the following way:
PropertyCallAdapterProvider<Foo>.GetInstance("Bar").InvokeGet(fooInstance)
Also, you can easily extend this for property setters if necessary.
On my machine those are the results for accessing the getter in loop ten million times, using various methods, when the adapter instance is pre-fetched from the provider before entering the loop:
141 milliseconds for direct invocation
244 milliseconds for adapter invocation
1800 milliseconds for reflection invocation
8179 milliseconds for dynamic delegate invocation