C# 动态转换为泛型类型

C# 动态转换为泛型类型,c#,generics,dynamic,type-conversion,castle-dynamicproxy,C#,Generics,Dynamic,Type Conversion,Castle Dynamicproxy,在周末到来之前,我只是想快点 我有一个具有以下签名的方法,需要调用该方法: public interface IObjectProvider<T> { T Get(Predicate<T> condition); } 正如您可能猜到的,编译器不允许我使用谓词变量作为参数。我需要做的是将这个对象转换成谓词,但是泛型类型params必须是编译时常量,所以这不起作用 我已经开始胡闹了,但到目前为止还没有成功: Type genericPredicateType = t

在周末到来之前,我只是想快点

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

public interface IObjectProvider<T>
{
    T Get(Predicate<T> condition);
}
正如您可能猜到的,编译器不允许我使用
谓词
变量作为参数。我需要做的是将这个对象转换成谓词,但是泛型类型params必须是编译时常量,所以这不起作用

我已经开始胡闹了,但到目前为止还没有成功:

Type genericPredicateType = typeof(Predicate<>);
Type specificPredicateType= genericPredicateType.MakeGenericType(relationTargetType);
Convert.ChangeType(predicate, specificPredicateType)
Type genericPredicateType=typeof(谓词);
类型specificPredicateType=genericPredicateType.MakeGenericType(relationTargetType);
ChangeType(谓词,specificPredicateType)
我到底怎样才能把它捣碎

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

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); }
    }
公共类秩序
{
公共虚拟int Id{get;set;}//或映射
公共虚拟日期时间OrderDate{get;set;}//或映射
[相关对象(类型(地址),“DeliveryAddressPredicate”)]
公共虚拟地址传递地址{get;set;}
公共谓词),我没有泛型类型param可用。因此,最后,这一切又归结为一个简单的.Net问题:我有一个
类型
存储在变量中,还有一个
方法
,必须使用上述类型的泛型参数调用它


对于所犯的任何错误(比如调用
var
a
Type
-这是一个很粗糙的人),非常抱歉;-)

你有一些
IObjectProvider
。如果
T
是编译时知道的类型,你可以使用cast。例如,如果
T
Foo

IObjectProvider<Foo> provider = …;
var predicate = (Predicate<Foo>)predicateProperty.GetValue(
    invocation.InvocationTarget, null);
Foo item = provider.Get(predicate);
  • 使用反射:

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

  • 这个问题显示了很多关于类型、变量等的混淆

    这句话毫无意义

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

    我想你是在说

    我有一些代码需要一个
    谓词

    您有一些返回
    对象
    的代码(您没有向我们展示)。您希望以某种方式将返回值强制转换为
    谓词
    。如果返回的对象是
    谓词
    ,则只需转到
    (谓词)retobj
    -您就完成了。如果它不是一个可以转换为
    谓词的类型,那么再多的抖动也不会使它成为
    谓词

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

    测试将为have ArrayList type

    什么是
    predicateProperty.GetValue
    ?PropertyInfo.GetValue-->对象的返回类型:-(该对象内部实际返回的类型是什么?
    Predicate
    ?只是一个旁白,但谓词不是
    var
    类型;
    var
    不是一个类型!@Eric,meh,可以明智地使用它。使用
    makegenericype
    并不是事实上的“非常讨厌”代码,但根据定义,它是泛型和反射的聚合。OP确实向我们展示了代码:
    predicateProperty.GetValue()
    。此外,强制转换到
    谓词只能在名为
    T
    的类型参数的泛型类型或方法内工作。否则,您需要指定一些具体类型,例如
    (谓词)retobj
    。此外,您不能将其他类型转换为
    谓词
    。例如,您不能将
    Func
    转换为
    谓词
    ,但可以使用构造函数形式的“抖动”来执行此操作:
    新谓词(Func)
    。谢谢你,斯维克。我会更新原来的帖子来澄清这个问题。pm100,你实际上把它归结为它的本质。我不能将对象转换为谓词(尽管它是谓词),因为我没有泛型类型参数T。我只有一个包含该类型的变量。请重新检查原始帖子。我在这里没有编译时支持。谢谢,Svick,这是我得到的最佳答案,我现在正在使用动态解决方案。如上所述,我尝试使用您的动态示例使其工作,但我继续运行into'CS1502:与…匹配的最佳重载方法有一些无效参数。')显然,动态类型没有正确解析为“Provider´-类中定义的静态类型。您知道这是如何发生的吗?您的意思是您得到了编译错误?您有关于错误的更多详细信息吗?哪一行导致了错误?还有其他原因吗er消息(类似于“参数1:无法从转换…”)?对象项=((动态)提供程序)。获取(谓词);不需要第二个参数。
    object provider = …;
    object predicate = predicateProperty.GetValue(
        invocation.InvocationTarget, null);
    var getMethod = provider.GetType().GetMethod("Get");
    object item = getMethod.Invoke(provider, new[] { predicate });
    
    public T CastToType<T>(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());