周末到来之前,简单说一下...
我有一个方法,具有以下签名,我需要调用它:
public interface IObjectProvider<T>
{
T Get(Predicate<T> condition);
}
这将为我提供一个符合谓词条件的来自任何类型来源的
T
。现在,必须从只有以下内容的上下文中调用此函数:
//the actual predicate that's going to be evaluated
var predicate = predicateProperty.GetValue(invocation.InvocationTarget, null);
//The type that should go into the call as type param
Type relationTargetType = relationDefinition.RelatedType;
正如你所猜测的那样,编译器不允许我使用“predicate”变量作为参数。我需要将此对象转换为Predicate,但泛型参数必须是编译时常量,因此这样做行不通。我已经开始尝试了一些方法,但目前还没有成功。
Type genericPredicateType = typeof(Predicate<>);
Type specificPredicateType= genericPredicateType.MakeGenericType(relationTargetType);
Convert.ChangeType(predicate, specificPredicateType)
我该如何混合这个东西?
编辑:我认为这是一个相当通用的问题,但显然我错了。既然有这么多关注我在做什么、我拥有什么以及为什么等等问题,那么在此提供更多背景信息。我正在尝试解决代理对象(Castle Dynamic Proxy)中的对象关系。以下代码片段应该能够解释我想要描述的关系类型:
public class Order
{
public virtual int Id { get; set; } // OR-Mapped
public virtual DateTime OrderDate { get; set; } // OR-Mapped
[RelatedObject(typeof(Address), "DeliveryAddressPredicate")]
public virtual Address DeliveryAddress { get; set; }
public Predicate<Address> DeliveryAddressPredicate
{
get { return new Predicate<Address>(a => OrderDate >= a.ValidFrom && OrderDate <= a.ValidTo); }
}
}
public class Address
{
public virtual DateTime ValidFrom { get; set; } // OR-Mapped
public virtual DateTime ValidTo { get; set; } // OR-Mapped
//Not OR-Mapped
[RelatedList(typeof(Order), "OrdersPredicate")]
public virtual IList<Order> Orders { get; set; }
public Predicate<Order> OrdersPredicate
{
get { return new Predicate<Order>(o => o.OrderDate >= ValidFrom && o.OrderDate <= ValidTo); }
}
总之,这应该成为一个模糊的OR映射,旨在扩展NHibernate中的一个或两个项目。
我是如何让它工作的?地址被代理,当使用我的CustomAttributes之一的属性进行调用时,我使用DynamicProxy的IInterceptor接口来解决关系。主要问题是这个解决必须发生在只有一个参数(see here)的IInterceptor.Intercept()方法中,而我没有泛型类型参数可用。因此,最终所有问题都归结为一个简单的.Net问题:我在一个变量中存储了一个Type,并且必须使用一个参数通用于上述类型的Method进行调用...
对于任何错误(例如将var称为Type-这真是一次艰难的经历),我表示歉意,今天过得很辛苦;-)
predicateProperty.GetValue
的返回类型是什么? - Chris ShainMakeGenericType
并不是“非常恶劣”的代码,但它确实是泛型和反射的交汇点。 - Kirk Woll