Dynamic cast to generic type

17,380

Solution 1

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

Solution 2

This question shows a lot of confusion about types, var etc.

This is a meaningless sentence

It is of type var and GetValue turned it into an object.

I think you are saying

I have some code that needs a Predicate<T>

You have some code (that you don't show us) that returns an Object. And want somehow to coerce that return value into a Predicate<T>. If the returned object is a Predicate<T> then simply go (Predicate<T>)retobj - and you are done. If it's not a type that can be cast to Predicate<T> then no amount of jiggling will make it into a Predicate<T>.

Share:
17,380
Sebastian Edelmeier
Author by

Sebastian Edelmeier

I am a MCTS Windows Forms Applications and Windows Presentation Foundation Applications I currently make people happy (or hope so) by implementing Full stack solutions (making heavy use of Angular) I used to spend my days on WPF, .Net, MVC and WebApi I love my family, piano and pencils

Updated on June 15, 2022

Comments

  • Sebastian Edelmeier
    Sebastian Edelmeier almost 2 years

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