Generic type cast

Just a rampage before the weekend at the weekend ...

I have a method with the following signature that I need to call:

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

This will provide me with T from any source matching the predicate criteria.

Now this needs to be called from the context where all I have is the following:

 //the actual predicate that 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 have guessed, the compiler will not allow me to use the variable predicate as a parameter. What I need to do is convert this object to Predicate, but the Generic type parameters should be compile constants, so this will not work.

I started talking with this, but so far have not achieved anything:

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

How can i do this?

EDIT: I thought it was more of a question than an agnostic, but obviously I was wrong. So, since there is such a fuss that I do what I have and why and something else, there is much more background information. I am trying to resolve relationships between objects in a proxy (Castle Dynamic Proxy). The following snippet should explain what relationship I want to portray:

 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 summarize, it is assumed that it will become a fuzzy OR-Mapping, designed to expand NHibernate in a project or two.

How did I want to make this work? The address is proxied, and when the property is called with one of my CustomAttributes, I use the DynamicProxy IInterceptor interface to resolve the relationship. The main problem is that this permission must happen in the IInterceptor.Intercept () method, which has only one Param parameter ( see here ), and I have no generic type parameter. So, in the end, it all comes down to a simple .Net question: I have a Type stored in a variable, and a Method that needs to be called with the generic parameter of the specified type ...

Sorry for any mistakes made (for example, calling var a Type - the person who was rude), it was quite a day; -)

+4
source share
3 answers

You have an IObjectProvider<T> . If T is a type known at compile time, you can simply use listing. 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 that you have two options:

  • Use dynamic :

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

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

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

This is a meaningless offer.

This is the type var and GetValue turned it into an object.

I think you say

I have code that needs a Predicate<T>

You have code (which you don’t show us) that returns Object . And you want to somehow make it return a value to Predicate<T> . If the returned object is a Predicate<T> , just go to the (Predicate<T>)retobj and you're done. If this is not a type that can be added to a Predicate<T> , then no offset will turn it into a Predicate<T> .

+1
source

I make this way

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

And like that

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

will be of type ArrayList

-1
source

Source: https://habr.com/ru/post/1403112/


All Articles