Seb*_*ier 5 c# generics castle-dynamicproxy dynamic type-conversion
在周末开始之前,请快点...
我有一个带有以下签名的方法,我需要调用:
public interface IObjectProvider<T>
{
T Get(Predicate<T> condition);
}
Run Code Online (Sandbox Code Playgroud)
这将为我提供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;
Run Code Online (Sandbox Code Playgroud)
正如您可能猜到的,编译器不会让我使用predicate变量作为参数.我需要做的是将此对象转换为谓词,但是泛型类型参数必须是编译时常量,因此这不起作用.
我已经开始搞乱这个,但到目前为止没有成功:
Type genericPredicateType = typeof(Predicate<>);
Type specificPredicateType= genericPredicateType.MakeGenericType(relationTargetType);
Convert.ChangeType(predicate, specificPredicateType)
Run Code Online (Sandbox Code Playgroud)
我怎么能把它捣碎呢?
编辑:我认为这是一个与用例无关的问题,但显然我错了.所以,既然对我所做的事情,我拥有的以及为什么以及诸如此类的事情有如此大惊小怪,这里有更多的背景信息.我试图解决代理(城堡动态代理)中的对象之间的关系.以下代码片段应该解释我想要描述的那种关系:
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); }
}
Run Code Online (Sandbox Code Playgroud)
总而言之,这应该成为一个模糊OR映射,意味着在一两个项目中扩展NHibernate.
我是怎么意思让这个工作的?代理地址,当使用我的CustomAttributes之一调用属性时,我使用DynamicProxy的IInterceptor接口来解析关系.主要的问题是这个解析必须在IInterceptor.Intercept()方法中发生,它只有一个Param(见这里),而且我没有可用的泛型类型param.所以,最后这一切归结为一个简单的.Net问题:我有一个Type存储在变量中,并且Method必须使用上述类型的泛型参数调用...
对不起任何错误(比如打电话var给Type那个粗糙的人),已经有一天了;-)
你有一些IObjectProvider<T>.如果T在编译时知道类型,则可以使用强制转换.例如,如果T是Foo:
IObjectProvider<Foo> provider = …;
var predicate = (Predicate<Foo>)predicateProperty.GetValue(
invocation.InvocationTarget, null);
Foo item = provider.Get(predicate);
Run Code Online (Sandbox Code Playgroud)
编辑:T在编译时似乎你不知道.这意味着您有两种选择:
用途dynamic:
object provider = …
object predicate = predicateProperty.GetValue(
invocation.InvocationTarget, null);
object item = ((dynamic)provider).Get((dynamic)predicate);
Run Code Online (Sandbox Code Playgroud)使用反射:
object provider = …;
object predicate = predicateProperty.GetValue(
invocation.InvocationTarget, null);
var getMethod = provider.GetType().GetMethod("Get");
object item = getMethod.Invoke(provider, new[] { predicate });
Run Code Online (Sandbox Code Playgroud)