public abstract class BaseClass
{
protected virtual int getValue() { return 1; }
}
I want to call getValue method.
typeof(BaseClass)
.GetMethod("getValue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.Invoke(null, new object[] { });
This code has a error.
Non static method requires a target
However, I cannot create instance of BaseClass because it is abstract class.
So, I am using dummy class which extends BaseClass.
class DummyClass : BaseClass { }
typeof(BaseClass)
.GetMethod("getValue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.Invoke(new DummyClass(), new object[] { });
I don't want to create dummy class every time if possible.
Is there a better way?
I agree with the other comments that this should not be production code, but out of fun it can certainly be done:
public static T CreateAbstractInstance<T>() where T : class =>
(T)Activator.CreateInstance(
Thread.GetDomain()
.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Run)
.DefineDynamicModule("DynamicModule")
.DefineType("DynamicType", TypeAttributes.Public | TypeAttributes.Class, typeof(T))
.CreateType());
private static TResult AbstractInvoke<TClass, TResult>(string methodName) where TClass : class
{
var method = typeof(TClass).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
var elegate = method.CreateDelegate(typeof(Func<BaseClass, TResult>));
return (TResult)elegate.DynamicInvoke(CreateAbstractInstance<TClass>());
}
private static void Main()
{
var result = AbstractInvoke<BaseClass, int>("getValue");
Console.WriteLine(result);
}
There is probably some method to trick the compiler and invoke it without even creating an instance, but I was getting too many Visual Studio crashes to carry on investigating other methods. Expressions seems to lead nowhere as at the end of the day, it still had to generate valid code so no way to trick an expression into an invalid lambda.
If you reuse a singleton instance from CreateAbstractInstance then you shouldn't have overheads after the first object is created (beside reflection usage if you invoke non public methods).
I thought I might add this to the answer as well:
I notice the comment about using it in a unit test; if you are using Moq (and probably most of the decent frameworks), you can do this:
var bc = new Mock<BaseClass>().Object;
// Invoke whatever you want on `bc` with reflection or not.
Although be aware that if the method is virtual it will automatically override it so you won't get by default the base class logic, but it can be solved setting up the mock.
You can try using an open instance delegate. Try this:
var method = typeof(BaseClass).GetMethod("getValue");
var func = (Func<BaseClass, int>) Delegate.CreateDelegate(typeof(Func<BaseClass, int>), method);
int result = func(null);
Note: The above technique works by omitting the hidden this parameter in the member call. This will only work if your method does not need to access the instance. If you attempt to access the instance, you will get a null reference exception.
Related
The question is somewhat related to this: How can I cast a delegate that takes a derived-type argument to a delegate with a base-type argument? but I have a dynamic situation.
So lets say I have two classes:
class Base
{ }
class Derived : Base
{ }
static class Workers
{
public static void DoSomething(Derived obj) { ... }
}
As you can see Workers.DoSomething is Action<Derived> and I want to cast it to Action<Base>. I know this is unsafe but my case is as follows: I keep a dictionary
Dictionary<Type, Action<Base>> actions;
and based on given objects obj.GetType() I retrieve one action and call it. And so I guarantee in my code that such action will be called with an appropriate type.
But those actions depend on the derived type obviously. Now the linked question suggests something like
actions[typeof(Derived)] = (obj) => Workers.DoSomething((Derived)obj);
This is ok in a situation when you know types at compile time. But in my case I retrieve them via reflection. So here's the setup
Type objType; // given
MethodInfo doSomethingMethod; // given, guaranteed to be Action<objType>
actions[objType] = // here what?
So far, surprisingly, the simplest solution I came up with is to create the method dynamically like follows:
Type objType; // given
MethodInfo doSomethingMethod; // given
var dynamicMethod = new DynamicMethod(
$"Dynamic{doSomethingMethod.Name}",
typeof(void),
new Type[] { typeof(Base) },
typeof(Base).Module
);
var il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Callvirt, doSomethingMethod, null);
il.Emit(OpCodes.Ret);
actions[objType] = (Action<Base>)dynamicMethod
.CreateDelegate(typeof(Action<Base>));
And so I force the call at CIL level. My real code is slightly more complicated since those actions accept two parameters. But that's just noise.
This works (and there's no cast as a bonus). But it looks kind of... I don't know, unsafe. And probably hard to maintain. Is there a better way to solve my problem?
Note: I want to avoid doSomethingMethod.Invoke due to its significant overhead.
Note 2: I have no control over those classes and actions. I can only inspect them.
You seem aware that you are turning the rules of covariance and contravariance upside-down, nevertheless here's something fairly tidy that may work for the situation you describe (you can also check that (b as Derived) != null just to be sure):
class Base { }
class Derived : Base { }
static class Workers
{
public static void DoSomething(Derived obj) { Console.WriteLine("Test"); }
}
class Program
{
static Dictionary<Type, Action<Base>> actions;
// *** Note use of dummy to avoid having to know T at compile time and T : Base constraint
// (compiler can't infer T from Action<T> alone, this way runtime works out T from given object instance)...
static void AddAction<T>(T dummy, Action<T> a) where T : Base
{
actions.Add(typeof(T), b => a(b as T));
}
static void Main(string[] args)
{
actions = new Dictionary<Type, Action<Base>>();
var o = new Derived(); // the object you get "from elsewhere"
AddAction(o, Workers.DoSomething);
actions[o.GetType()](o);
Console.ReadKey();
}
}
Hope this is useful. (Very curious about the "Why?" though ;-)
I can't claim this as my idea, but found it here: https://stackoverflow.com/a/32702091/1848953 while researching your question.
First:
private static Action<object> ConvertDelegateToAction<T>(Delegate d) { return obj => ((Action<T>)d)((T)obj); }
private static readonly MethodInfo CastMethodInfo = typeof(Program).GetMethod(nameof(ConvertDelegateToAction), BindingFlags.Static | BindingFlags.NonPublic);
used:
public static Action<object> GetActionT(Type t, Delegate d) { return (Action<object>)CastMethodInfo.MakeGenericMethod(t).Invoke(null, new object[] { d }); }
Quite tidy I think. You GetType() at runtime and use Invoke() but only to get the Action<object> up-front. (Instead of a base class, I used an empty interface. Seemed to work fine.)
Let us know if this gives satisfaction.
Can you create a delegate of an instance method without specifying the instance at creation time? In other words, can you create a "static" delegate that takes as it's first parameter the instance the method should be called on?
For example, how can I construct the following delegate using reflection?
Func<int, string> = i=>i.ToString();
I'm aware of the fact that I can use methodInfo.Invoke, but this is slower, and does not check for type-correctness until it is called.
When you have the MethodInfo of a particular static method, it is possible to construct a delegate using Delegate.CreateDelegate(delegateType, methodInfo), and all parameters of the static method remain free.
As Jon Skeet pointed out, you can simply apply the same to make an open delegate of an instance method if the method is non-virtual on a reference type. Deciding which method to call on a virtual method is tricky, so that's no so trivial, and value-types look like they don't work at all.
For value types, CreateDelegate exhibits really weird behavior:
var func37 = (Func<CultureInfo,string>)(37.ToString);
var toStringMethod = typeof(int).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, new Type[] {typeof(CultureInfo) }, null);
var func42 = (Func<CultureInfo,string>)Delegate.CreateDelegate(typeof(Func<CultureInfo,string>), 42, toStringMethod,true);
Console.WriteLine( object.ReferenceEquals(func37.Method,func42.Method)); //true
Console.WriteLine(func37.Target);//37
Console.WriteLine(func42.Target);//42
Console.WriteLine(func37(CultureInfo.InvariantCulture));//37
Console.WriteLine(func42(CultureInfo.InvariantCulture));//-201040128... WTF?
Calling CreateDelegate with null as the target object throws a binding exception if the instance method belonged to a value type (this works for reference types).
Some follow-up years later: The incorrectly-bound target that caused func42(CultureInfo.InvariantCulture); to return "-201040128" instead of "42" in my example was memory corruption that could have allowed remote code execution (cve-2010-1898); this was fixed in 2010 in the ms10-060 security update. Current frameworks correctly print 42! That doesn't make answering this question any easier, but explains the particularly weird behavior in the example.
You've actually chosen a particularly tricky example, for two reasons:
ToString() is a virtual method inherited from object but overridden in Int32.
int is a value type, and there are weird rules with Delegate.CreateDelegate() when it comes to value types and instance methods - basically the first effective parameter becomes ref int rather than int
However, here's an example for String.ToUpper, which doesn't have either of those problems:
using System;
using System.Reflection;
class Test
{
static void Main()
{
MethodInfo method = typeof(string).GetMethod
("ToUpper", BindingFlags.Instance | BindingFlags.Public,
null, new Type[]{}, null);
Func<string, string> func = (Func<string, string>)
Delegate.CreateDelegate(typeof(Func<string, string>),
null,
method);
string x = func("hello");
Console.WriteLine(x);
}
}
If that's good enough for you, great... if you really want int.ToString, I'll have to try a bit harder :)
Here's an example for a value type, using a new delegate type which takes its first parameter by reference:
using System;
using System.Reflection;
public struct Foo
{
readonly string value;
public Foo(string value)
{
this.value = value;
}
public string DemoMethod()
{
return value;
}
}
class Test
{
delegate TResult RefFunc<TArg, TResult>(ref TArg arg);
static void Main()
{
MethodInfo method = typeof(Foo).GetMethod
("DemoMethod", BindingFlags.Instance | BindingFlags.Public,
null, new Type[]{}, null);
RefFunc<Foo, string> func = (RefFunc<Foo, string>)
Delegate.CreateDelegate(typeof(RefFunc<Foo, string>),
null,
method);
Foo y = new Foo("hello");
string x = func(ref y);
Console.WriteLine(x);
}
}
I'm not sure, but may be Open delegates can help you.
Upd: Follow this link, if first one don't works.
You could use Lambdas to get a "somewhat" compiled static wrapper for your instance method.
The sample below isn't exactly blazingly fast, yet it should be significantly faster than any plain dynamic invoke.
The output
100000 iterations took 4 ms
1000000 iterations took 18 ms
10000000 iterations took 184 ms
The code
class Program
{
public sealed class Test
{
public String Data { get; set; }
public override string ToString()
{
return Data;
}
}
static void Main(string[] args)
{
TestRun(100000);
TestRun(1000000);
TestRun(10000000);
}
private static void TestRun(int iterations)
{
var toString = typeof(Test).GetMethod("ToString",
BindingFlags.Instance
| BindingFlags.Public,
null,
Type.EmptyTypes,
null);
var call = GetCall<Test, String>(toString);
var tests
= (from i in Enumerable.Range(1, iterations)
select new Test { Data = "..." + i }).ToList();
var sw = Stopwatch.StartNew();
tests.ForEach(i => call(i));
sw.Stop();
Console.WriteLine("{0} iterations took {1} ms", iterations, sw.ElapsedMilliseconds);
}
private static Func<T, M> GetCall<T, M>(MethodInfo methodInfo)
{
var input = Expression.Parameter(typeof(T), "input");
MethodCallExpression member = Expression.Call(input, methodInfo);
var lambda = Expression.Lambda<Func<T, M>>(member, input);
return lambda.Compile();
}
}
The goog way maybe can be useing the "dynamic" type in .NET 4.0. However the Delegate need the instance (for non-static methods). The problems is more complex then lokks at first time because of polymorfism etc...
I'm presently working on a project that includes tests with RhinoMocks mocked objects. Since upgrading to RhinoMocks 3.6.1 from 3.6.0 previously working project code is failing during testing. The issue seems to be caused by changed behavior of mock objects between versions. The generated Mock objects are now Castle Proxy objects that don't appear to be reflectable. Previously it was possible to gather MethodInfo from a mocked object via reflection, which no longer seems to be the case. Should I be setting up my mocks in a different way?
A greatly simplified example follows:
Given an interface to be mocked
public interface IValidator<in T>
{
bool Validate(T obj);
}
in testing code the mock is created with an expectation:
var validator = MockRepository.GenerateMock<IValidator<string>>();
validator.Expect(v => v.Validate(Arg<string>.Is.Equal("input")))
.Return(true);
...
// the validator object is then passed into a consumer and assertions
// are checked to be sure the consumer and validator appropriately
// behave (outside scope of question)
Within the consumer class reflection is done to get the "Validate" method from the interface in order to be invoked during standard execution:
var method = validator.GetType()
.GetMethod("Validate", BindingFlags.Public | BindingFlags.Instance);
The crux of the issue is method is now null when using the update version of RhinoMocks as reflection no longer seems to work.
The root of my issue is the inability to reflect on the proxy object generated by Rhino / Castle when all I have are instances an no ability to do explicit casting.
I know this might get me punched in the face.
But if you are in a generic class you could quite easily do something like
var method = typeof(IValidator<T>).GetType()
.GetMethod("Validate", BindingFlags.Public | BindingFlags.Instance);
Also if the project is very large and there are alot of tests and mocks, this may be a huge amount of rework :(
EDIT:
Ok round 2 :)
The problem seems to be in the fact that the mock is a dynamic class and does not actually seem to have that method.
How about instead of using GetMethod you create an interface (ITypeHelper) that has a number of wrapper methods for getting types and methods.
Normally these would just call the methods directly (so as to not cause any perfomance penalties), but during testing you could swap out your implementation of ITypeHelper for a MockTypeHelper (by changing the registration in the container or some other mechanisim).
public class RhinoMocks_33901386
{
//public static ITypeHelper TypeHelper = new TypeHelper();
//use when testing
public static ITypeHelper TypeHelper = new MockTypeHelper();
public static void Run()
{
var validator = MockRepository.GenerateMock<IValidator<string>>();
validator.Expect(v => v.Validate(Arg<string>.Is.Equal("input"))).Return(true);
var method = TypeHelper.GetMethod(validator.GetType(), "Validate");
var result = (bool) method.Invoke(validator, new object[] {"input"});
Console.WriteLine(result);
Console.WriteLine("Done");
Console.ReadLine();
}
}
public interface IValidator<in T>
{
bool Validate(T obj);
}
public interface ITypeHelper
{
MethodInfo GetMethod(Type self, string name);
}
public class TypeHelper : ITypeHelper
{
public virtual MethodInfo GetMethod(Type self, string name)
{
return self.GetMethod(name);
}
}
public class MockTypeHelper : ITypeHelper
{
public virtual MethodInfo GetMethod(Type self, string name)
{
if (typeof(IMockedObject).IsAssignableFrom(self) && self.BaseType == typeof(object))
{
self = self.GetInterfaces()
.First(x => x != typeof(IMockedObject) && x != typeof(ISerializable) && x != typeof(IProxyTargetAccessor));
}
return self.GetMethod(name);
}
}
Hope I'm getting warmer ;p
It seems like RihnoMocks or Castle DynamicProxy has changed how it works internally. As #sQuir3l pointed out, it seems to be using dynamic objects internally.
In this particular case you can work around the change by accessing the underlying interface type like this:
var method = ((IMockedObject)validator).ImplementedTypes
.Single(type => type == typeof(IValidator<string>))
.GetMethod("Validate", BindingFlags.Public | BindingFlags.Instance);
I have class and interface:
public class TestClass : ITestInterface
{
public int GetStatus()
{
return -1;
}
}
public interface ITestInterface
{
int GetStatus();
}
and I would like to dynamically create subclass of TestClass which will look like:
public class TestClass2 : TestClass
{
public new int GetStatus()
{
return base.GetStatus();
}
}
I have some code which can create subclasses and overrides all virtual methods but when method is virtual final (GetStatus) I'm getting:
"Declaration referenced in a method implementation cannot be a final method."
Any ideas how it can be done?
PS: I can post code mentioned if you'd like.
EDIT 1:
'Some code':
public static T GetSubClass<T>() where T : class
{
var builder = DefineType<T>();
DefineOverrideMethods(builder, typeof(T));
var type = CreateType(builder);
return (T)Activator.CreateInstance(type);
}
private static TypeBuilder DefineType<T>() where T : class
{
return _moduleBuilder.DefineType("Proxy_" + typeof (T).Name,
TypeAttributes.Sealed | TypeAttributes.Class | TypeAttributes.Public, typeof (T));
}
private static void DefineOverrideMethods(TypeBuilder builder, Type type)
{
foreach (var virtualMethodInfo in GetVirtualMethods(type))
{
var parameters = GetMethodParametersTypes(virtualMethodInfo);
var newMethodInfo = DefineNewVirtualMethod(builder, virtualMethodInfo, parameters);
var il = newMethodInfo.GetILGenerator();
var local = EmitCreateLocal(il, newMethodInfo);
EmitCallBaseMethod(il, virtualMethodInfo);
EmitSaveReturnToLocal(il, local);
EmitReturnMethod(il, virtualMethodInfo, local);
builder.DefineMethodOverride(newMethodInfo, virtualMethodInfo);
}
}
private static IEnumerable<MethodInfo> GetVirtualMethods(Type type)
{
return type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(q => q.IsVirtual);
}
private static Type[] GetMethodParametersTypes(MethodInfo virtualMethodInfo)
{
return virtualMethodInfo.GetParameters().Select(q => q.ParameterType).ToArray();
}
private static MethodBuilder DefineNewVirtualMethod(TypeBuilder builder, MethodInfo virtualMethodInfo, Type[] parameters)
{
return builder.DefineMethod(virtualMethodInfo.Name,
MethodAttributes.Public | MethodAttributes.Virtual,
virtualMethodInfo.ReturnType, parameters);
}
private static void EmitSaveReturnToLocal(ILGenerator il, LocalBuilder local)
{
il.Emit(OpCodes.Stloc_S, local);
il.Emit(OpCodes.Ldloc_S, local);
}
private static LocalBuilder EmitCreateLocal(ILGenerator il, MethodBuilder newMethodInfo)
{
return il.DeclareLocal(newMethodInfo.ReturnType);
}
private static Type CreateType(TypeBuilder builder)
{
builder.DefineDefaultConstructor(MethodAttributes.Public);
var type = builder.CreateType();
return type;
}
private static void EmitReturnMethod(ILGenerator il, MethodInfo methodInfo, LocalBuilder local)
{
il.Emit(OpCodes.Ldloc_S, local);
il.Emit(OpCodes.Ret);
}
private static void EmitCallBaseMethod(ILGenerator il, MethodInfo virtualMethodInfo)
{
ushort index = 0;
while (index < virtualMethodInfo.GetParameters().Length + 1)
il.Emit(OpCodes.Ldarg, index++);
il.Emit(OpCodes.Call, virtualMethodInfo);
}
Exception is throwed at var type = builder.CreateType();
EDIT 2:
#Rahul:
Language is C# and as you can see in method 'GetVirtualMethods' there is property 'IsVirtual'.
Property 'IsFinal' exists there too and returns true for 'GetStatus' method.
EDIT 3:
#Wim.van.Gool:
Yes you are right - I can not override non virtual methods. What I am trying to do here is to hide base implementation of 'GetStatus' with dummy implementation which calls base method.
Why it would be useful? Imagine that method 'GetSubClass' returns you a class that behaves like base but for example have added log methods before and after base implementation calls.
#MichaĆ Komorowski:
Thank you for answer. It works, but only partially. Program do not throws error anymore but in this example:
ITestInterface obj = StaticClass.GetSubClass<TestClass>();
obj.GetStatus();
'GetStatus' method is called directly from base (TestClass) not from dynamically created subclass.
I tried to add: builder.AddInterfaceImplementation(typeof(ITestInterface)); but it did not make any difference.
EDIT 4:
#danish: Thank you for answer. It is now working. NewSlot saves problem.
Actually whole attribute data: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual.
Thank you guys for helping. Unfortunately I can not mark both answers as a correct ones but both were significant for resolving problem.
Whenever a class implements an interface method, CLR needs that method to be marked as virtual and also final is set to true. However in reality this method is not really virtual. To get actual virtual methods, you need to check IsVirtual for true and IsFinal for false.
In your case, you are actually looking for hiding the intended behaviour. Hence a new method needs to be created and emitted for sub class. From what I understand, NewSlot method attribute will shadow the base class method(can someone confirm? I am not too sure about this one).
The problem is that you are actually trying to override a method that is not virtual. You have 2 options. The first one is to make TestClass.GetStatus method virtual. When you do it you will be able to override it. The second solution is to hide this method. It seems to me that your code will work if you:
Remove the following line builder.DefineMethodOverride(newMethodInfo, virtualMethodInfo);
In DefineNewVirtualMethod method use MethodAttributes.HideBySig instead of MethodAttributes.Virtual.
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.