[英]Cast type in a generic method to a different one for inner generic method call
I've got this repository method: 我有这个存储库方法:
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
}
defined in a 3-rd party assembly: 在第三方聚会中定义:
public class Record<T> where T : Record<T>, IRecordBase, new()
{
public static Record<T> FetchByID(object primaryKey) { /*...*/ }
}
My T
and the 3-rd party T
are not directly compatible, however my objects that inherit from Record<T>
also also implement IDalRecord
, so i can cast the object instance to any of these type. 我的
T
和第3方T
不是直接兼容的,但是我从Record<T>
继承的对象也实现了IDalRecord
,所以我可以将对象实例转换为这些类型中的任何一种。
But how can i tell the compiler to "cast" (IDalRecord)T
to (Record<T>)T
? 但是我怎么能告诉编译器“转换”
(IDalRecord)T
到(Record<T>)T
?
There is no way to tell the compiler that T
actually inherits from Record<T>
. 没有办法告诉编译器
T
实际上是从Record<T>
继承的。 The reason is simple: because it is not true, generally speaking. 原因很简单:一般来说,这不是真的。 Indeed, your
Get
method may, theoretically, be called with any argument, not necessarily that inheriting from Record<T>
. 实际上,理论上,你的
Get
方法可以用任何参数调用,不一定是从Record<T>
继承的。
The fact that T
does, in fact, inherit from Record<T>
only becomes known at runtime, when your method is actually called. 事实上,
T
实际上从Record<T>
继承的事实只有在实际调用方法时才会在运行时知道。 Therefore, necessary checks and constructs must take place at that same moment. 因此,必须在同一时刻进行必要的检查和构造。
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);
}
Keep in mind that is it entirely possible (and even encouraged) to cache those Helper<T>
objects for performance. 请记住,完全可能(甚至鼓励)缓存这些
Helper<T>
对象以提高性能。
You can also just use old dumb reflection: find the method FetchByID by name and call it dynamically. 您也可以使用旧的哑反射:按名称查找方法FetchByID并动态调用它。 But that would cause enormous performance penalty.
但这会导致巨大的性能损失。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.