动态转换为通用类型 [英] Dynamic cast to generic type

查看:157
本文介绍了动态转换为通用类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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

  public interface IObjectProvider< T> 
{
T Get(Predicate< T>条件);
}

这将为我提供一个 T 从任何类型的源,符合谓词条件。



现在,这必须从上下文中调用,我所拥有的是以下内容: / p>

  //要评估的实际谓词
var predicate = predicateProperty.GetValue(invocation.InvocationTarget,null) ;

//应该进入调用的类型为param
键入relationTargetType = relationDefinition.RelatedType;

您可能会猜到,编译器不会让我使用谓词变量作为参数。我需要做的是将此对象转换为谓词,但通用类型参数必须是编译时常量,因此这将不起作用。



开始搞砸了这个,但迄今没有成功:

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



编辑:我认为这是一个非常用例无关的问题,但显然我错了。所以,既然有这么一个我所做的事情,我有什么,为什么和什么,这里有更多的背景信息。我试图解决代理(Castle Dynamic Proxy)中的对象之间的关系。以下代码片段应该解释我想描述的关系类型:

  public class Order 
{
public virtual int Id {get;组; } // OR-Mapped
public virtual DateTime OrderDate {get;组; } // OR-Mapped

[RelatedObject(typeof(Address),DeliveryAddressPredicate)]
public virtual Address DeliveryAddress {get;组; }

public Predicate< Address> DeliveryAddressPredicate
{
get {return new Predicate< Address>(a =" OrderDate> = a.ValidFrom&& OrderDate< = a.ValidTo); }
}
}

public class Address
{
public virtual DateTime ValidFrom {get;组; } // OR-Mapped
public virtual DateTime ValidTo {get;组; } // OR-Mapped

//不是OR-Mapped
[RelatedList(typeof(Order),OrdersPredicate)]
public virtual IList< Order>订单{get;组; }

public Predicate< Order> OrdersPredicate
{
get {return new Predicate< Order>(o => o.OrderDate> = ValidFrom&& o.OrderDate< = ValidTo); }
}

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



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



对不起,出现任何错误(如调用 var a 类型 - 这是一个粗糙的人),已经相当一天了; - )

解决方案

你有一些 IObjectProvider< T> 。如果 T 是一个在编译时知道的类型,您只需使用一个转换。例如,如果 T Foo

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

编辑:似乎你不知道 T 在编译时。这意味着你有两个选择:


  1. 使用动态 p>

      object provider = ... 
    object predicate = predicateProperty.GetValue(
    invocation.InvocationTarget,null);
    object item =((dynamic)provider).Get((dynamic)predicate);


  2. 使用反射:

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



Just a quickie before the weekend rolls in...

I have a Method with the following signature, that I need to invoke:

public interface IObjectProvider<T>
{
    T Get(Predicate<T> condition);
}

This will provide me with a T from whatever kind of source, that meets the predicate criteria.

Now, this has to be called from a context where all I have is the following:

//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;

As you might guess, the compiler won't let me use the predicate variable as parameter. What I need to do is convert this object into a Predicate, but Generic type params must be compile-time-constant, so this won't work.

I've started messing around with this, but no success so far:

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

How on earth can I mash this up?

EDIT: I thought this was a rather use-case-agnostic question, but obviously I was wrong. So, since there is such a fuss as to what I do, what I have and why and whatnot, here's a lot more background info. I am trying to resolve relations between objects in a Proxy (Castle Dynamic Proxy). The following Snippet should explain the kind of relation I want to depict:

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); }
    }

To sum it up, this is supposed to become a Fuzzy OR-Mapping, meant to extend NHibernate in a project or two.

How did I mean to get this to work? The address is proxied, and when a call to a property with one of my CustomAttributes is made, i use DynamicProxy's IInterceptor interface to resolve the relation. The main problem is that this resolving has to happen in the IInterceptor.Intercept() Method which has only one Param (see here), and I have no generic type param available. So, in the end it all boils down to a simple .Net question again: I have a Type stored in a variable and a Method that has to be called with a parameter generic of the aforesaid type...

Sorry for any mistakes made (like calling var a Type - man that was a rough one), it's been quite a day ;-)

解决方案

You have some IObjectProvider<T>. If T is a type know at compile-time, you can just use a cast. For example, if T was Foo:

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

EDIT: It seems you don't know T at compile time. This means you have two options:

  1. Use dynamic:

    object provider = …
    object predicate = predicateProperty.GetValue(
        invocation.InvocationTarget, null);
    object item = ((dynamic)provider).Get((dynamic)predicate);
    

  2. Use reflection:

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

这篇关于动态转换为通用类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆