我想为泛型方法创建一个Shim。但在这种情况下,我对通用药有点麻烦。
以下是我的例子:
class BaseRepository <T> where T: Entity
{
public T[] FindAll()
{
return Method<T>.FindAll()
}
}
class ClassA : base<A>
{
}
class A : Entity
{
}
class ClassB : base<B>
{
}
class B : Entity
{
}现在我想为ClassA和ClassB创建一个ClassB
ShimBaseRepository<A>.AllInstances.FindAll = (repo) => MethodA();
ShimBaseRepository<B>.AllInstances.FindAll = (repo) => MethodB();
public A MethodA()
{
//Make the Same as MethodB
}
public B MethodB()
{
//Make the Same as MethodA
}但是如果我有超过20个“基本”类呢?我不想为每个baseClass创建一个委托/方法。我试过这样的方法:
List<Type> allEntityClasses = (from x in Assembly.GetAssembly(typeof(Entity)).GetTypes()
where !x.IsAbstract && !x.IsInterface
select x).ToList();
foreach(Type type in allEntityClasses=
{
ShimBaseRepository<type????>.AllInstances.FindAll = (repo) => Method();
}
public Entity????? Method()
{
}在我的Unittest中,我将使用以下方法:
ClassA.FindAll()
ClassB.FindAll()而不是:
Base.FindAll()编辑:我使用微软的赝品,所以我不能改变ShimClass中的任何东西。下面是从Shim生成的源代码。
public class ShimBaseRepository<T> : ShimBase<BaseRepository<T>> where T : Entity
{
public static class AllInstances
{
public static FakesDelegates.Func<BaseRepository<T>, T[]> FindAll { [ShimMethod("FindAll", 20)] set; }
}
}我的意图是,我不想为每个实体创建一个委托,我只想遍历我的所有EntityClasses并动态创建委托。但是我不知道如何将Type对象添加到
ShimBase<T>发布于 2015-03-17 08:58:55
好吧,让我们讨论一下。首先,这里有一个使用虚拟方法的直进解决方案:
public class Base<T> where T : Entity
{
public virtual T[] FindAll()
{
return null;
}
}然后,只需在具体的类中重写FindAll,或者,如果可以的话,也可以将Base抽象和InnerFindAll抽象。
但是,如果您需要在运行时指定委托(正如我所看到的那样,您有一个特定的帮助程序,但我无法得到,为什么在Base中调用助手,然后使用一个Func函数在问题AllInstances中有一些未定义的),这种方法不会有帮助。您需要使用在Base中分配的默认策略来实现战略模式。然后,在具体的类中有3种“解决”策略的方法:
T)返回合适的策略另外,我认为你在设计上有一些问题。我不认为您需要将FindAll实现为注入Func<T>类型的静态属性的lambda (是的,我认为您可以用一个static FindAll代替AllInstances.FindAll )。所以如果我是你,我会用抽象的方法。
编辑
现在我知道你的问题了,只能通过反思给你一个很难看的解决方案.我不建议你用这个,因为它真的很严格
public class Program
{
static void Main(string[] args)
{
List<Type> allEntityClasses = (from x in Assembly.GetAssembly(typeof(Entity))
.GetTypes().Where(t=>typeof(Entity).IsAssignableFrom(t))
where !x.IsAbstract && !x.IsInterface
select x).ToList();
foreach (var type in allEntityClasses)
{
var genericType = typeof(BaseGeneric<>).MakeGenericType(type);
var helper = new DelegateHelper();
var myLambda = helper.GetLambdaForType(type);
var allInst = genericType.GetProperty("AllInstances").GetValue(null);
if (allInst == null)
{
allInst = Activator.CreateInstance(genericType.GetProperty("AllInstances").PropertyType);
}
allInst.GetType().GetProperty("FindAll").SetValue(allInst,myLambda);
}
}
}
public static class BaseGeneric<T>
{
public static AllInstances<T> AllInstances { get; set; }
}
public class AllInstances<T>
{
public Func<T[]> FindAll { get; set; }
}
public class DelegateHelper
{
public Delegate GetLambdaForType(Type type)
{
var funcType = typeof(Func<>).MakeGenericType(type.MakeArrayType());
var methodInfo = typeof(DelegateHelper).GetMethods().FirstOrDefault(t => t.Name == "FunctionMethod")
.MakeGenericMethod(type);
var @delegate = methodInfo.CreateDelegate(funcType, this);
return @delegate;
}
public T[] FunctionMethod<T>()
{
return new T[10];
}
}
public class Entity
{
}
public class EntityFirst
{
}
public class EntitySecond
{
}https://stackoverflow.com/questions/29093896
复制相似问题