Call a private member of the base class using ImpromptuInterface

I have a structure that allows me to access the state and methods of objects in my project using the keyboard. It relies heavily on ImpromptuInterface , which is large, fast and flexible and durable.

For example, I call methods with Impromptu.InvokeMember(myObject, methodName, castParameters) . It worked great for public and private users, but when I try to call a private member of the myObject base class, I get Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'MyType.MyMethod(Something)' is inaccessible due to its protection level .

The simplest code that shows the problem:

 public class MainClass { public static void Main(string[] args) { var type = new PublicType(); var other = new OtherType(); Console.WriteLine(Impromptu.InvokeMember(other, "Method", 2)); //works Console.WriteLine(Impromptu.InvokeMember(type, "Method", 2)); //crash } } public class PublicType : OtherType {} public class OtherType { private bool Method(object a) { return a != null; } } 

I understand why such a problem exists, and I see some possible permissions, for example, searching for a class where the method is defined and trying to pass my object to this class, but this is quite troublesome.

Is there any simple solution, preferably based solely on Impromptu?

+4
source share
1 answer

So the way to work with DLR is to call the Type context so that it can determine which methods are available. By default, impromptu uses the type of the object you are calling, so it usually works with most private methods, but obviously not from the base classes.

In your case, you need to create your own improvisation context, which is mentioned in the UsagePrivate documentation, it works later as the interfaces. It is also unclear from the documentation, but the fact is that you can pass a typeof () object for context. So in your example you can:

 var context = InvokeContext.CreateContext; Console.WriteLine(Impromptu.InvokeMember(context(type, typeof(OtherType)), "Method", 2)); 

If you need to do this for general cases, itโ€™s not very, but you can always catch the exception and recursively try the base type, since in the general case it works for the first time, there should be no slowdown, and class hierarchies are usually not very deep, and since you just do it interactively once, not thousands of times, it should be fine.

 var context = InvokeContext.CreateContext; var type = target.GetType() while(true){ try{ Console.WriteLine(Impromptu.InvokeMember(context(target, type), "Method", 2)); break; }catch(RuntimeBinderException ex){ type = type.BaseType; if(type ==null) throw ex; } } 
+2
source

All Articles