我有这个存储库方法:
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
?
答案 0 :(得分:5)
没有办法告诉编译器T
实际上是从Record<T>
继承的。原因很简单:一般来说,这不是真的。实际上,理论上,您的Get
方法可以使用任何参数调用,而不一定是从Record<T>
继承的参数。
实际上,T
从Record<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并动态调用它。但这会造成巨大的性能损失。