Reflection Gurus: Why aren't my MethodInfo objects equal? - c#

Basically, some internal check that happens in the static System.Linq.Expressions.Expression.Bind() method says "Method is not a property accessor" on my property that is clearly a property. Using Reflector, I've minimized the amount of code causing the problem, and I can't for the life of me figure out why this would happen. My only guess is that it has something to do with the fact that the property isn't on the class itself, but I would think this should still work:
I've tried to make a small example with the least amount of code possible. The code below should run in its entirety.
using System;
using System.Reflection;
public class Base
{
public virtual int Id { get; set; }
}
// As you can see, SubClass does not override the Id property of Base.
public class SubClass : Base { }
class Program
{
static void Main(string[] args)
{
// Getting the property directly from the type.
PropertyInfo propertyInfo = typeof(SubClass).GetProperty("Id");
MethodInfo setMethod = propertyInfo.GetSetMethod();
/* Code from here on out is from the System.Linq.Expressions.Bind() method (the one
that accepts a MethodInfo argument). This method causes GetProperty to be called
and retrieve what should be the same PropertyInfo. It fails here, saying something
along the lines of "Method is not a property accessor." which doesn't make sense. */
PropertyInfo propertyInfo2 = GetProperty(setMethod);
}
private static PropertyInfo GetProperty(MethodInfo mi)
{
// Not sure if it matters, but declaringType here is "Base".
Type declaringType = mi.DeclaringType;
BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public;
bindingAttr |= mi.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
foreach (PropertyInfo info in declaringType.GetProperties(bindingAttr))
{
// For the "Id" property, info.CanRead is true, but CheckMethod is false.
if (info.CanRead && CheckMethod(mi, info.GetGetMethod(true)))
return info;
// For the "Id" property, info.CanWrite is true, but CheckMethod is false.
if (info.CanWrite && CheckMethod(mi, info.GetSetMethod(true)))
return info;
}
// This gets thrown after passing by the "Id" property that is the one I'm looking for.
throw new Exception("Method is not a property accessor");
}
private static bool CheckMethod(MethodInfo method, MethodInfo propertyMethod)
{
// These are not equal, so it goes to the next check. In the debugger, they appear identical when I look through the object tree.
if (method == propertyMethod)
return true;
Type declaringType = method.DeclaringType;
return ((declaringType.IsInterface && (method.Name == propertyMethod.Name)) && (declaringType.GetMethod(method.Name) == propertyMethod));
}
}
If anyone could help I would greatly appreciate it! I'm very much lost at this point.
Edit - If you substitute typeof(SubClass) with typeof(Base), it works, so it's something related to that relationship. I guess I could cut the issue off at the root by making an extension method like typeof(SubClass).GetPropertyFromActualClass("Id") but I'm not sure how to perform that check.

The property and method infos of Base and SubClass are indeed not equal, even if SubClass has no own implementation, as can be seen here:
var subPropertyInfo = typeof(SubClass).GetProperty("Id");
var subPropertyInfoSetter = subPropertyInfo.GetSetMethod();
var basePropertyInfo = typeof(Base).GetProperty("Id");
var basePropertyInfoSetter = basePropertyInfo.GetSetMethod();
Console.WriteLine(subPropertyInfo == basePropertyInfo); // false
Console.WriteLine(subPropertyInfoSetter == basePropertyInfoSetter); // false
If you use mi.ReflectedType instead of mi.DeclaringType, the check succeeds:
var type = subPropertyInfoSetter.ReflectedType;
Console.WriteLine(type.GetProperty("Id").GetSetMethod()
== subPropertyInfoSetter); // true

Related

Fastest way for Get Value of a property (Reflection) in C#

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

Get Value Of PropertyInfo

I'm creating a small validation framework, I've a custom Validation Attribute which is assignable to methods and a IsValid property in ValidationCore class. When IsValid called inside the method my ValidationCore finds a caller method and get its attribute assigned to method. My custom Validation attribute has a property name named TypeToValidate. So when I find validation attribute I look for any types in class scope of that type. I don't have any problem till now, but the problem is when I want to get the value of property which I've to validate I don't have any instance of that class to get that property value. I don't know how can I handle this situation please help me.
This is my sample :
public class TestClass
{
public static TestModel Model { get; set; }
public static ModelValidator ModelState
{
get { return new ModelValidator(); }
}
[Validate(typeof(TestModel))]
public static void DoSomething()
{
if (ModelState.IsValid)
{
// Do something else....
}
}
}
Edit : This is my IsValid property
public virtual Boolean IsValid
{
get
{
// Get IsValid caller method
var method = GetCallerMethod();
// Get method attribute
var Attrib = GetMethodAttribute(typeof(ValidateAttribute), method);
// Get model to validate inside class scope
var modelProperty = GetModelToValidateInClassScope(Attrib, method);
if (modelProperty != null)
{
ValidateModel(modelProperty);
}
....
}
}
and here is ValidateModel method :
protected virtual void ValidateModel(PropertyInfo modelProperty)
{
// Here I've model property
// But I can't get its value
var model = modelProperty.GetValue(null, null);
var properties = model.GetType().GetProperties(
BindingFlags.FlattenHierarchy |
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly);
foreach (var propertyInfo in properties)
{
// Add error to error list
GetPropertyErrors(model, propertyInfo);
}
}
Thanks in advance.
You need an instance for which to get the property value of. It looks like you need to modify the method GetModelToValidateInClassScope so that it returns the instance of the model itself, along with the PropertyInfo.
If this method is changed so it looks something like this (note the new out parameter):
PropertyInfo GetModelToValidateInClassScope(Type attributeType, MethodInfo methodInfo, out object instance)
{
// same implementation as before ...
// assign the model to use,
// which is likely accessible from somewhere in the is method
instance = theModelInstanceFromThisMethod;
// .. or if the property is static, then uncomment the next line:
// instance = null;
// same return value as before ...
}
I'm just guessing here because you didn't provide the implementation of this method. If GetModelToValidateInClassScope doesn't have access to the model instance, then you'll have to get it from somewhere else.
Once you get the model instance, it could be used like the following. Note that ValidateModel has been modified so that it accepts the model instance as the first parameter.
...
// Get model to validate inside class scope
object instance; // <--- will hold the model instance
var modelProperty = GetModelToValidateInClassScope(Attrib, method, out instance);
if (modelProperty != null)
{
ValidateModel(instance, modelProperty); // <--- make sure to pass the instance along!
}
...
protected virtual void ValidateModel(object instance, PropertyInfo modelProperty)
{
// get value of instance property
var model = modelProperty.GetValue(instance, null);
...
}
Answer to the question actually asked
I don't have any problem till now, but the problem is when I want to get the value of property which I've to validate I don't have any instance of that class to get that property value.
If it's a static property, that's fine - just use null as the first argument:
// First argument is the instance: null as it's a static property
// Second argument is indexer arguments: null as we don't have any
var value = property.GetValue(null, null);
From the documentation:
Because static properties belong to the type, not individual objects, get static properties by passing null as the object argument.
Alternative approach
If you're just trying to get the TypeToValidate property from the Validate attribute, then you should have an instance of the attribute, and you can just cast to ValidateAttribute and retrieve the property directly.
Basically, it's not clear where properties really come into what you're trying to do. Your attribute is on a method rather than a property, and your attribute doesn't say which properties to validate...

Getting baseclass property value using reflection - base.Property as opposed to this.Property

I want to know if something like this is possible: I've overriden a property of a base class, which is auto-implemented. I've supplied logic in the override to resolve "missing" properties against default settings.
Now, I want to use reflection to check whether the default value is used or some "actual" value. In other words, I need to check if base.Property is null, but by using reflection. This doesn't work, it simply gets the sub-class value (which is resolved against defaults, so not null).
var property = this.GetType().GetProperty(e.PropertyName);
if(property.GetValue(this, null) == null))
OnPropertyChanged(e.PropertyName);
Also tried:
var property = this.GetType().BaseType.GetProperty(e.PropertyName);
if(property.GetValue(this, null) == null))
OnPropertyChanged(e.PropertyName);
Is it possible using reflection to access the base class value?
UPDATE:
Following advice from comments, I tried the following, just for kicks.
var method1 = this.GetType().BaseType.GetMethods().First(x => x.Name.Contains(e.PropertyName));
var method = this.GetType().BaseType.GetProperty(e.PropertyName).GetGetMethod();
var methodValue = method1.Invoke(this, null);
Both of these still return the "derived" value, while at the same time base.Property returns null.
It is possible, although as far as I know there's no way to do it without emitting your own IL, basically using the call instruction rather than callvirt.
Note that if you need to go to these lengths to make your design work then that's a sign that you're probably doing something wrong somewhere!
Anyway, here's a contrived example. (Error-checking etc omitted for brevity.)
var derived = new DerivedClass();
Console.WriteLine(derived.GetBaseProperty("Prop")); // displays "BaseProp"
// ...
public class BaseClass
{
public virtual string Prop { get; set;}
}
public class DerivedClass : BaseClass
{
public override string Prop { get; set;}
public DerivedClass()
{
base.Prop = "BaseProp";
this.Prop = "DerivedProp";
}
public object GetBaseProperty(string propName)
{
Type t = this.GetType();
MethodInfo mi = t.BaseType.GetProperty(propName).GetGetMethod();
var dm = new DynamicMethod("getBase_" + propName, typeof(object), new[] { typeof(object) }, t);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, mi);
if (mi.ReturnType.IsValueType) il.Emit(OpCodes.Box, mi.ReturnType);
il.Emit(OpCodes.Ret);
var getBase = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>));
return getBase(this);
}
}
AFAIK I think it is not possible. The real type of the object is the derived type, and by definition of virtual methods, no matter through which type instance (actual type or base type) you call a method, you will get the overriden implementation.
Having this work any other way would be, at least to me, unexpected behavior.
EDIT: I have tried the following to see if it is actually possible to get to the base implentation:
Type baseType = this.GetType().BaseType;
var methodInfo = baseType.GetMethod("Foo");
string foo = methodInfo.Invoke(this, null); //Derived type implementation
This means that even calling the method through the base type MethodInfo reflection is able to resolve the override and will return the derived implementation. So I think what you are trying is not possible through reflection or at least I can not see a way to do it.

Determine whether a C# method has keyword 'override' using Reflection

I had expected to find an answer easily to this problem, but I didn't.
I'd like to know if it is possible to determine whether a method has the keyword 'override' attributed to it, given its instance of MethodInfo.
I was thinking maybe the following would achieve that:
/// <summary> Returns whether the specified methodInfo is attributed with the keyword 'override'. </summary>
public static bool IsOverriding(this MethodInfo methodInfo)
{
if (methodInfo == null) throw new ArgumentNullException();
return methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType;
}
I've sucessfully tested some non-virtual, virtual and abstract examples, but I feel like I'm missing some scenarios, maybe with hiding or generics(although I can't figure out how that would come into play).
I try to find this thing also. From the question, you give the idea to get IsOverriding work for override keyword. However for hiding I try to create IsHiding for keyword new. Here is the basic C# OOP:
override only used when the based method contain abstract or virtual modifier.
new is used to hide based method with the same name but...
new cannot be apply to abstract base method because it generate compiler error.
However the interesting part is new also can be applied to method if the base method contain virtual.
The inseresting part is we can hide or override virtual method. We know that GetBaseDefinition() will return the base MethodInfo if we override a virtual method. but the key to differentiate it is the GetBaseDefinition() will return the same MethodInfo instead of it base MethodInfo if we hiding virtual method.
override keyword is a must while new is only used to suppress the warning message. So we can diffrentiate override and new by the IsAbstract and IsVirtual combine with DeclaringType and BaseType.
public static bool IsOverriding(this MethodInfo methodInfo)
{
if (methodInfo == null) throw new ArgumentNullException("methodInfo");
return methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType;
}
public static bool IsHiding(this MethodInfo methodInfo)
{
if (methodInfo == null) throw new ArgumentNullException("methodInfo");
if (methodInfo.DeclaringType == methodInfo.GetBaseDefinition().DeclaringType)
{
var baseType = methodInfo.DeclaringType.BaseType;
if (baseType != null)
{
MethodInfo hiddenBaseMethodInfo = null;
var methods = baseType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Static);
foreach (var mi in methods)
if (mi.Name == methodInfo.Name)
{
var miParams = mi.GetParameters();
var methodInfoParams = methodInfo.GetParameters();
if (miParams.Length == methodInfoParams.Length)
{
var i = 0;
for (; i < miParams.Length; i++)
{
if (miParams[i].ParameterType != methodInfoParams[i].ParameterType
|| ((miParams[i].Attributes ^ methodInfoParams[i].Attributes).HasFlag(ParameterAttributes.Out))) break;
// Simplified from:
//if (miParams[i].ParameterType != methodInfoParams[i].ParameterType
// || (miParams[i].Attributes.HasFlag(ParameterAttributes.Out) && !methodInfoParams[i].Attributes.HasFlag(ParameterAttributes.Out))
// || !(miParams[i].Attributes.HasFlag(ParameterAttributes.Out) && methodInfoParams[i].Attributes.HasFlag(ParameterAttributes.Out))) break;
}
if (i == miParams.Length)
{
hiddenBaseMethodInfo = mi;
break;
}
}
}
if (hiddenBaseMethodInfo != null && !hiddenBaseMethodInfo.IsPrivate) return true;
}
}
return false;
}
I test it using the simple inheritance and it works. I don't think about generic method..yet..
EDIT: I just change the code above because I forgot the idea about inherited type can contain newly declared method which is should not threated as new. IsHiding() will first make sure it have the same DeclaringType (it seems like new) but need to look at the base declaring types by DeclaringType.BaseType if a method with the same name exist.
Note that because of there is no BindingFlags.DeclaredOnly, GetMethod() will search through the entire base types, so no need to recursively search to each base types. BindingFlags.FlattenHierarchy is used to include static method in abstract-abstract base class like this:
public abstract class A
{
public static void Stat() { }
}
public abstract class B : A
{
}
public class C: B
{
public new static void Stat() { }
}
EDIT: I just fix the IsHiding() above to check for base method overloads and prevent AmbiguousMatchException by using GetMethods() instead of GetMethod(). The overloads tested to work with combination with different parameters, mix with ref, out, params and optional parameter. Signature for overloads being compared based on parameter count, parameter types and its modifier:
ref or out included in the signature but both cannot be overloaded to each other.
return type, optional (default value) and params on right most parameter should be ignored
ref compared by the ParameterType itself (see the ending '&' during debugging) and no need to compare by the IsByRef while the out compared by the Attributes flag. I am using simplified expression bitwise XOR to skip the loop if and only if one of the attributes has flag Out which makes the signature different. Don't confused with HasFlag in .NET 4, it just want to make sure Out bit is 1 by the XOR result.
Well, I don't see how that would come into play either. Your code there does indeed determine whether a method is defined or overriden.
In the case of hiding, the declaring type is the one that hides the method via new.
In the case of generics, all methods are defined by the template class.
You can try this
public static bool IsOverriding(this MethodInfo methodInfo)
{
if (methodInfo == null) throw new ArgumentNullException();
return methodInfo.GetBaseDefinition() != methodInfo;
}

Get generic type of call to method in dynamic object

I'm starting to work with dynamic objects in .Net and I can't figure out how to do something.
I have a class that inherits from DynamicObject, and I override the TryInvokeMember method.
e.g.
class MyCustomDynamicClass : DynamicObject
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
// I want to know here the type of the generic argument
}
}
And inside that method I want to know the type (if any) of the generic arguments in the invocation.
e.g.
If I invoke the following code, I want to get the value of System.Boolean and System.Int32 inside the overrided method of my dynamic object
dynamic myObject = new MyCustomDynamicClass();
myObject.SomeMethod<bool>("arg");
myObject.SomeOtherMethod<int>("arg");
Currently if I place a breakpoint inside the overrided method I can get the name of the method being invoked ("SomeMethod" and "SomeOtherMethod", and also the values of the arguments, but not the generic types).
How can I get these values?
Thanks!
Actually I looked through the hierarchy of the binder and found a property with the needed values in the internal fields of the object.
The problem is that the property isn't exposed because it uses C#-specific code/classes, therefore the properties must be accessed using Reflection.
I found the code in this japanese blog: http://neue.cc/category/programming (I don't read any japanese, therefore I'm not sure if the author actually describes this same issue
Here's the snippet:
var csharpBinder = binder.GetType().GetInterface("Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder");
var typeArgs = (csharpBinder.GetProperty("TypeArguments").GetValue(binder, null) as IList<Type>);
typeArgs is a list containing the types of the generic arguments used when invoking the method.
Hope this helps someone else.
A bit of googling and I have quite generic solution for .NET and Mono:
/// <summary>Framework detection and specific implementations.</summary>
public static class FrameworkTools
{
private static bool _isMono = Type.GetType("Mono.Runtime") != null;
private static Func<InvokeMemberBinder, IList<Type>> _frameworkTypeArgumentsGetter = null;
/// <summary>Gets a value indicating whether application is running under mono runtime.</summary>
public static bool IsMono { get { return _isMono; } }
static FrameworkTools()
{
_frameworkTypeArgumentsGetter = CreateTypeArgumentsGetter();
}
private static Func<InvokeMemberBinder, IList<Type>> CreateTypeArgumentsGetter()
{
if (IsMono)
{
var binderType = typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).Assembly.GetType("Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder");
if (binderType != null)
{
ParameterExpression param = Expression.Parameter(typeof(InvokeMemberBinder), "o");
return Expression.Lambda<Func<InvokeMemberBinder, IList<Type>>>(
Expression.TypeAs(
Expression.Field(
Expression.TypeAs(param, binderType), "typeArguments"),
typeof(IList<Type>)), param).Compile();
}
}
else
{
var inter = typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).Assembly.GetType("Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder");
if (inter != null)
{
var prop = inter.GetProperty("TypeArguments");
if (!prop.CanRead)
return null;
var objParm = Expression.Parameter(typeof(InvokeMemberBinder), "o");
return Expression.Lambda<Func<InvokeMemberBinder, IList<Type>>>(
Expression.TypeAs(
Expression.Property(
Expression.TypeAs(objParm, inter),
prop.Name),
typeof(IList<Type>)), objParm).Compile();
}
}
return null;
}
/// <summary>Extension method allowing to easyly extract generic type arguments from <see cref="InvokeMemberBinder"/>.</summary>
/// <param name="binder">Binder from which get type arguments.</param>
/// <returns>List of types passed as generic parameters.</returns>
public static IList<Type> GetGenericTypeArguments(this InvokeMemberBinder binder)
{
// First try to use delegate if exist
if (_frameworkTypeArgumentsGetter != null)
return _frameworkTypeArgumentsGetter(binder);
if (_isMono)
{
// In mono this is trivial.
// First we get field info.
var field = binder.GetType().GetField("typeArguments", BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
// If this was a success get and return it's value
if (field != null)
return field.GetValue(binder) as IList<Type>;
}
else
{
// In this case, we need more aerobic :D
// First, get the interface
var inter = binder.GetType().GetInterface("Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder");
if (inter != null)
{
// Now get property.
var prop = inter.GetProperty("TypeArguments");
// If we have a property, return it's value
if (prop != null)
return prop.GetValue(binder, null) as IList<Type>;
}
}
// Sadly return null if failed.
return null;
}
}
Have fun. By the way Impromptu is cool, but I can't use it.
The open source framework Dynamitey can call properties that internal/protected/private using the DLR and thus works with Silverlight. But it get's a little tricky with interface explicit members as you have to use the actual full name of the member on the the type, rather than the interface member name. So you can do:
var typeArgs = Dynamic.InvokeGet(binder, "Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder.TypeArguments")
as IList<Type>;

Categories