泛型静态缓存和协方差
本文关键字:方差 缓存 静态 泛型 | 更新日期: 2023-09-27 18:34:05
我试图构建一个静态通用缓存,它将保存Apply(Event e(形式的几种方法的方法信息。在 RedirectToWhen(来自 CQRS Lokad 框架(中使用了类似的代码。
问题是泛型缓存不考虑派生类(如果有(。这是一个显示意外行为的简单测试:
[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( 返回 AbstractType,所以我不能用它来构建一个通用的静态缓存。如何为派生类型获取方法的泛型缓存?
使用
instance.GetType()
如果实例不为空,并且类型(T( OS 实例为空。
我知道
这有点坏死,但我遇到了同样的问题,typeof(T( 返回基本类型。当想要创建实现 Emit/Apply 模式的 BaseAggregate 时,这很有用。我是这样解决的:
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;
}
}
这仍然缓存得很好,object.GetType()
返回要馈送到此方法的正确类型。