动态转换为generics类型

在周末开始之​​前,请快点…

我有一个带有以下签名的方法,我需要调用:

public interface IObjectProvider { T Get(Predicate 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变量作为参数。 我需要做的是将此对象转换为谓词,但通用类型参数必须是编译时常量,所以这不起作用。

我已经开始搞乱这个,但到目前为止没有成功:

 Type genericPredicateType = typeof(Predicate); Type specificPredicateType= genericPredicateType.MakeGenericType(relationTargetType); Convert.ChangeType(predicate, specificPredicateType) 

我怎么能把它混在一起呢?

编辑:我认为这是一个与用例无关的问题,但显然我错了。 所以,既然对我所做的事情,我拥有的以及为什么以及诸如此类的事情有这样的大惊小怪,这里有更多的背景信息。 我试图解决代理(城堡动态代理)中的对象之间的关系。 以下代码片段应该解释我想要描述的那种关系:

 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
DeliveryAddressPredicate { get { return new Predicate
(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 Orders { get; set; } public Predicate OrdersPredicate { get { return new Predicate(o => o.OrderDate >= ValidFrom && o.OrderDate <= ValidTo); } }

总而言之,这应该成为模糊OR映射,意味着在一两个项目中扩展NHibernate。

我是怎么意思让这个工作的? 代理地址,当使用我的CustomAttributes之一调用属性时,我使用DynamicProxy的IInterceptor接口来解析关系。 主要问题是这个解析必须在IInterceptor.Intercept()方法中发生,它只有一个Param( 见这里 ),我没有可用的generics类型参数。 所以,最后这一切归结为一个简单的.Net问题:我有一个存储在变量中的Type和一个必须用上述类型的generics参数调用的Method ……

对不起任何错误(比如调用var a Type – 那个粗略的人),已经有一天了;-)

你有一些IObjectProvider 。 如果T是编译时知道的类型,则可以使用强制转换。 例如,如果TFoo

 IObjectProvider provider = …; var predicate = (Predicate)predicateProperty.GetValue( invocation.InvocationTarget, null); Foo item = provider.Get(predicate); 

编辑:看来你在编译时不知道T 这意味着您有两种选择:

  1. 使用dynamic

     object provider = … object predicate = predicateProperty.GetValue( invocation.InvocationTarget, null); object item = ((dynamic)provider).Get((dynamic)predicate); 
  2. 使用reflection:

     object provider = …; object predicate = predicateProperty.GetValue( invocation.InvocationTarget, null); var getMethod = provider.GetType().GetMethod("Get"); object item = getMethod.Invoke(provider, new[] { predicate }); 

这个问题显示了很多关于类型,var等的混淆。

这是一个毫无意义的句子

它的类型为var,GetValue将其转换为对象。

我想你是在说

我有一些需要Predicate代码

您有一些返回Object代码(您没有向我们展示)。 并希望以某种方式将该返回值强制转换为Predicate 。 如果返回的对象是Predicate那么只需去(Predicate)retobj – 然后就完成了。 如果它不是可以转换为Predicate的类型,则没有任何数量的抖动会使其成为Predicate

我这样做

 public T CastToType(object objType, T type) where T : class { var cast = objType as T; if(cast == null) throw new InvalidCastException(); return cast; } 

就像这样

 var test = CastToType(objType, new ArrayList()); 

test将具有ArrayList类型