将泛型方法中的类型转换为内部泛型方法调用的不同方法

时间:2011-10-30 01:22:08

标签: c# .net generics casting

我有这个存储库方法:

    public virtual T Get<T>(object primaryKey) where T : IDalRecord, new() //note: can't change the where clause
    {
        return Record<T>.FetchByID(primaryKey); // how? <--compile time error
    }

在第三方聚会中定义:

    public class Record<T> where T : Record<T>, IRecordBase, new()
    {
        public static Record<T> FetchByID(object primaryKey) { /*...*/ }
    }

我的T和第3方T不是直接兼容的,但是从Record<T>继承的对象也会实现IDalRecord,因此我可以投放对象实例到任何这些类型。

但是我如何告诉编译器“强制转换”(IDalRecord)T(Record<T>)T

1 个答案:

答案 0 :(得分:5)

没有办法告诉编译器T实际上是从Record<T>继承的。原因很简单:一般来说,这不是真的。实际上,理论上,您的Get方法可以使用任何参数调用,而不一定是从Record<T>继承的参数。

实际上,TRecord<T>继承的事实只有在实际调用方法时才会在运行时知道。因此,必须在同一时刻进行必要的检查和构造。

interface IHelper { object Fetch(object key); }

class Helper<T> : IHelper where T : Record<T>, IRecordBase, new()
{
    public object Fetch(object key) { return Record<T>.FetchByID(key); }
}

public virtual T Get<T>(object primaryKey) where T : IDalRecord, new()
{
    var helperType = typeof( Helper<> ).MakeGenericType( typeof( T ) );
      // This will throw an exception if T does not satisfy Helper's where clause

    var helper = Activator.CreateInstance( helperType ) as IHelper; 
    return (T) helper.Fetch(primaryKey);
}

请记住,完全可能(甚至鼓励)缓存这些Helper<T>对象以提高性能。

您也可以使用旧的哑反射:按名称查找方法FetchByID并动态调用它。但这会造成巨大的性能损失。