I was trying to build a static generic cache which is going to hold method info of several methods of the form Apply(Event e). A similar code is used in RedirectToWhen, from CQRS Lokad framework.
The problem is that the generic cache doesn't consider derived classes if any. This is a simple test that shows the undesired behavior:
[TestMethod]
public void TestGenericsInheritance()
{
var sut = new DerivedFromAbstractType();
Utils.UsefulMethod<DerivedFromAbstractType>(sut);
Assert.AreEqual(10, sut.Value);
}
public abstract class AbstractType
{
public int Value { get; set; }
}
public class DerivedFromAbstractType : AbstractType
{
public void AnyOtherMethod()
{
Value = 10;
}
}
public static class Utils
{
public static void UsefulMethod<T>(T instance)
{
MethodInfo info = typeof(T)
.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(m => m.Name == "AnyOtherMethod")
.Where(m => m.GetParameters().Length == 0).FirstOrDefault();
info.Invoke(instance,null);
}
}
typeof(T) returns AbstractType, so I can't use it to build a generic static cache. How could I get a generic cache for methods awared of derived types?
use
instance.GetType()
if instance is not null and typeof(T) os instance is null.
I know this is necro-ing a bit, but I had the same problem, with typeof(T) returning the base type. This is useful when wanting to create a BaseAggregate which implements an Emit/Apply pattern. I solved it like this :
private static class Cache
{
private static readonly IDictionary<Type, IDictionary<Type, MethodInfo>> _dict =
new Dictionary<Type, IDictionary<Type, MethodInfo>>();
public static IDictionary<Type, MethodInfo> GetDictionaryForType(Type type)
{
if (_dict.ContainsKey(type))
{
return _dict[type];
}
var dict = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(m => m.Name == "When")
.Where(m => m.GetParameters().Length == 1)
.ToDictionary(m => m.GetParameters().First().ParameterType, m => m);
_dict.Add(type, dict);
return dict;
}
}
This still caches nicely, and object.GetType()
returns the correct type to be fed into this method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.