Mux*_*uxa 4 .net c# 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
}
Run Code Online (Sandbox Code Playgroud)
在第三方聚会中定义:
public class Record<T> where T : Record<T>, IRecordBase, new()
{
public static Record<T> FetchByID(object primaryKey) { /*...*/ }
}
Run Code Online (Sandbox Code Playgroud)
我T
和第三方T
不是直接兼容的,但是我继承的对象Record<T>
也实现了IDalRecord
,所以我可以将对象实例转换为这些类型中的任何一种.
但是,我怎么能告诉编译器"投" (IDalRecord)T
到(Record<T>)T
?
没有办法告诉编译器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);
}
Run Code Online (Sandbox Code Playgroud)
请记住,完全可能(甚至鼓励)缓存这些Helper<T>
对象以提高性能.
您也可以使用旧的哑反射:按名称查找方法FetchByID并动态调用它.但这会导致巨大的性能损失.
归档时间: |
|
查看次数: |
180 次 |
最近记录: |